Haskell-flavoured functions for Go :smiley:

Overview

Hasgo Mentioned in Awesome Go Build Status

Hasgo is a code generator with functions influenced by Haskell. It comes with some types out-of-the-box so you can start using it without running the generator. Specifically you can start using Hasgo's Strings and Ints types.

We want to focus on being:

  • Immutable
  • Strongly-Typed (no interface{})
  • Nil-safe

Pie

The inspiration for Hasgo, as well as some ideas around implementation come from the lovely Pie library, made by Elliot Chance. It's safe to say that Hasgo would not exist without Pie. However, the way Pie and Hasgo work is not the same and neither is the focus of the project. If you don't find a function in Hasgo, check out Pie! ๐Ÿ˜ƒ

Example

import . "github.com/DylanMeeus/hasgo/types"
func EpicFunction() {
	// create a range of -10 -> 10. Take the absolute values, keep only even numbers, and sum them.
	result := IntRange(-10,10).
		Abs().
		Filter(func(i int64) bool {
			return i % 2 == 0
		}).
		Sum()
	// result = 60 
}

You can find more examples here.

Installation

go get -u github.com/DylanMeeus/hasgo

Or add hasgo to your go.mod file.

require github.com/DylanMeeus/hasgo/v1.0.2

Types

  • Ints ([]int64)
  • Strings ([]string)

Functions

These are the function currently available with Hasgo. It shows you which type of data they operate on as well as the Haskell type definition. The first symbol of the signature is actually the method receiver in Go terms.

Alternatively, you can consult the godoc

Generic functions

These functions can be generated for every type.

Function Signature String Number Struct Description
Abs [a] -> [a] โœ“ Return a slice containing the absolute values
All [a] -> (a -> bool) -> bool โœ“ โœ“ โœ“ Returns true if the predicate applies to all elements in the slice
Any [a] -> (a -> bool) -> bool โœ“ โœ“ โœ“ Returns true if one or more elements satisfy the predicate
Average [a] -> a โœ“ Returns the average of all elements
Break (a -> bool) -> [a] -> ([a], [a]) โœ“ โœ“ โœ“ Returns a tuple of all elements until the first one that matches the predicate, followed by the remaining elements.
Delete [a] -> a -> [a] โœ“ โœ“ โœ“ Returns the slice with the first occurance of the element deleted.
Drop Int -> [a] -> [a] โœ“ โœ“ โœ“ Returns the suffix of xs after the first n elements.
DropWhile (a -> bool) -> [a] -> [a] โœ“ โœ“ โœ“ Returns the suffix of xs after the predicate's first failure.
Elem [a] -> a -> bool โœ“ โœ“ โœ“ Returns true if the slice contains the element.
Filter [a] -> (a -> bool) -> [a] โœ“ โœ“ โœ“ Filter the slice based on a predicate
Foldl [a] -> a -> (a -> a -> a) -> a โœ“ โœ“ โœ“ Left fold over the slice to reduce it to one element with starting value.
Foldl1 [a] -> (a -> a -> a) -> a โœ“ โœ“ โœ“ Left fold over the slice to reduce it to one element.
Foldr [a] -> b -> (a -> b -> b) -> b โœ“ โœ“ โœ“ Right fold over the slice to reduce it to one element with a starting value.
Foldr1 [a] -> (a -> a -> a) -> a โœ“ โœ“ โœ“ Right fold over the slice to reduce it to one element.
Group [a] -> [[a]] โœ“ โœ“ โœ“ Returns a list of lists where each list contains grouped values from the input list.
Head [a] -> a โœ“ โœ“ โœ“ Return the first element
Init [a] -> [a] โœ“ โœ“ โœ“ Returns all elements minus the last
Inits [a] -> [[a]] โœ“ โœ“ โœ“ Returns all initial segments of the slice, shortest first.
Intercalate [a] -> [[a]] -> [a] โœ“ โœ“ โœ“ Intersperses the slice in between the provided 2d-slice
Intersperse [a] -> a -> [a] โœ“ โœ“ โœ“ Intersperses the value in between all elements of the provided slice
IsPrefixOf [a] -> [a] -> bool โœ“ โœ“ โœ“ Returns true if the current slice is a prefix of the provided slice
Last [a] -> a โœ“ โœ“ โœ“ Returns the last element
Length [a] -> int โœ“ โœ“ โœ“ Returns the length of the slice
Map [a] -> (a -> a) -> [a] โœ“ โœ“ โœ“ Returns a slice with the function applied to each element of the input
Maximum [a] -> a โœ“ Returns the largest element
MaximumBy [a] -> (a -> a) -> a -> a โœ“ โœ“ โœ“ Returns the maximum element according to comparator
Minimum [a] -> a โœ“ Returns the lowest element
Modes [a] -> [a] โœ“ โœ“ โœ“ Returns the elements with the highest frequency
Nub [a] -> [a] โœ“ โœ“ โœ“ Returns a Slice containing one of each of the input elements
Null [a] -> bool โœ“ โœ“ โœ“ Returns true if the slice is empty, false otherwise
Product [a] -> a โœ“ Returns the product of all elements in the slice.
Reverse [a] -> [a] โœ“ โœ“ โœ“ Returns a slice with the elements reversed
Scanl [a] -> b -> (a -> b -> a) -> [b] โœ“ โœ“ โœ“ Left fold over the slice to reduce it to one element with a starting value and return every iteration in a slice.
Sort [a] -> [a] โœ“ โœ“ Returns a sorted slice (original remains unsorted)
Span (a -> bool) -> [a] -> ([a], [a]) โœ“ โœ“ โœ“ Returns a tuple of all elements until the first one that does not match the predicate, followed by the remaining elements.
SplitAt Int -> [a] -> ([a], [a]) โœ“ โœ“ โœ“ Returns a tuple with all elements up until the specified index, followed by the elements after the index.
Sum [a] -> a โœ“ โœ“ โœ“ The sum of elements in the slice
Tail [a] -> [a] โœ“ โœ“ โœ“ Returns all elements minus the first
Tails [a] -> [[a]] โœ“ โœ“ โœ“ Returns all final segments of the slice, longest first.
Take [a] -> uint64 -> [a] โœ“ โœ“ โœ“ Take N elements from the slice, or all if N exceeds the length.
TakeWhile [a] -> (a -> bool) -> [a] โœ“ โœ“ โœ“ Take all elements until the first one that does not match the predicate.
Uncons [a] -> (a, [a]) โœ“ โœ“ โœ“ Returns a tuple of the head and tail of the slice
Unlines [a] -> string โœ“ โœ“ โœ“ Returns a newline separated string of all elements in the slice
Unwords [a] -> string โœ“ โœ“ โœ“ Returns a space-separated string of all elements in the slice

Hardcoded functions

The built-in types (Strings, Ints, Bools) have some functions defined on them that are not generated. Mostly because we could not create them in a generic way.

Type Function Signature Description
Ints Equals *Ints -> Ints -> bool Returns true if both slices contain the same elements
Ints EqualsOrdered *Ints -> Ints -> bool Returns true if both slices contain the same elements, in the same position
Ints IntRange int64 -> int64 -> Ints Return an integer range from [start,stop]
Ints IntReplicate uint64 -> int64 -> Ints Return a slice with the input element repeated n times
Strings Equals *Strings -> Strings -> bool Returns true if both slices contain the same elements
Strings EqualsOrdered *Strings -> Strings -> bool Returns true if both slices contain the same elements, in the same position
Strings Lines string -> Strings Returns Strings separated by a newline.
Strings StringReplicate uint64 -> string -> Strings Return a slice with the input element repeated n times
Strings Words string -> Strings Returns Strings separated by a space.
Bools And Bools -> bool Returns true if all bools are true.
Bools Or Bools -> bool Returns true if any bool is true.

* (Functions prefixed by a star are functions added to the type itself, where first element in the signature is the method receiver. So for examples, the Equals method is Ints{1,2}.Equals(Ints{1}). But, the IntRange function looks like hasgo.IntRange(0,10).

Contributing

You can help out Hasgo in a variety of ways! Here are some ideas:

  • Use Hasgo! ๐Ÿ˜ƒ
  • Spread the word (Write a blog, tweet, talk about..)
  • Suggest features (Create an issue to make a suggestion)
  • Report bugs (Similarly, create an issue)
  • Contribute code. (Create a PR, we'll gladly take a look and help you get it merged!)

What's in a name?

The name Hasgo is a portmanteau of "Haskell" and "Go". I'm a big fan of both languages, though they are quite different. It's impossible to write real Haskell-like code in Go. There are some obvious differences between the languages in terms of syntax. I hope the functions in this library stay as close as possible to their Haskell implementations. There might be extra functions in here that are not in Haskell, and there will be functions in Haskell that you won't find here.

The inspiration mainly shows in the naming of functions. If the functions were named after Java lambdas, it'd be called "Jago". Sorry if you expected more Haskell goodness (I'm open to suggestions of how more haskell in Hasgo!)

Real Generics?

Currently I have an experimental implementation of hasgo here as hasgo2. It does require a development version of Go installed from source to function correctly at this stage.

Comments
  • Unit test for nil

    Unit test for nil

    Some functions' unit tests don't test for nil as receiver / input. Need to go over the unit tests and make sure they all test for this and return the expected result. (Similar for the empty slice which seems to be present more often)

    good first issue hacktoberfest 
    opened by DylanMeeus 6
  • test for nil/empty Strings

    test for nil/empty Strings

    In addition to creating unit test scenarios for nil and empty Strings, I also modified the test for Sort such that there is a test verifying the sort behavior for the output and a test verifying the original input is untouched.

    hacktoberfest-accepted 
    opened by GoFightNguyen 4
  • Replicate

    Replicate

    Create a slice of length given by the first argument and the items having value of the second argument.

    |Haskell|Proposed Go| |---|---| |replicate 3 5|IntReplicate(3, 5)| |replicate 3 "x"|StringReplicate(3, "x")|

    enhancement 
    opened by xcgpseud 2
  • Foldr func

    Foldr func

    I kept the element order of Foldl in Hasgo ([a] -> a -> (a -> a -> a) -> a) although Haskell defines it as (a -> b -> b) -> b -> [a] -> b which is Hasgo would be [a] -> (a -> a -> a) -> a -> a.

    Need to verify that this is how we want to keep it prior to merge @DylanMeeus.

    opened by xcgpseud 1
  • Fix Foldl function which wasn't working correctly

    Fix Foldl function which wasn't working correctly

    Haskell's foldl should use the init on the first iteration rather than the last. A simple change has corrected this behaviour.

    image

    image

    See images above for Haskell behaviour to verify.

    opened by xcgpseud 1
  • isPrefixOf

    isPrefixOf

    isPrefixOf :: Eq a => [a] -> [a] -> Bool
    

    The isPrefixOf function takes two lists and returns True iff the first list is a prefix of the second.

    >>> "Hello" `isPrefixOf` "Hello World!"
    True
    >>> "Hello" `isPrefixOf` "Wello Horld!"
    False
    

    In Hasgo:

    Ints{1, 2, 3}.IsPrefixOf(Ints{1, 2, 3, 4})
    
    opened by xcgpseud 1
  • Drop function

    Drop function

    Implement the drop function:

    drop :: Int -> [a] -> [a]

    drop n xs returns the suffix of xs after the first n elements, or [] if n > length xs:

    drop 6 "Hello World!" == "World!"
    drop 3 [1,2,3,4,5] == [4,5]
    drop 3 [1,2] == []
    drop 3 [] == []
    drop (-1) [1,2] == [1,2]
    drop 0 [1,2] == [1,2]
    
    enhancement 
    opened by xcgpseud 1
  • TakeWhile function

    TakeWhile function

    takeWhile :: (a -> Bool) -> [a] -> [a]

    takeWhile, applied to a predicate p and a list xs, returns the longest prefix (possibly empty) of xs of elements that satisfy p:

    hacktoberfest 
    opened by DylanMeeus 1
  • Generator breaks when using %v formatting in function

    Generator breaks when using %v formatting in function

    When creating a function containing the statement:

    fmt.Sprtinf("%v\n",v)
    

    The code that gets generated is erroneous, in the form of:

    fmt.Sprintf("%(MISSING)",v)
    
    bug 
    opened by DylanMeeus 1
  • Boolean type

    Boolean type

    Several functions in Haskell's Data.List package apply specifically to list of booleans. We could introduce such a datatype ourselves, but I question the utility.

    One created issue is currently blocked by missing this type: #35

    exploratory 
    opened by DylanMeeus 1
  • Add type funcs to Readme

    Add type funcs to Readme

    Functions defined in types such as IntRange and IntReplicate etc. aren't currently in the readme as they don't adhere to the same format as other functions.

    We may want a go docs page for this?

    enhancement 
    opened by xcgpseud 1
  • Upgrade to GitHub-native Dependabot

    Upgrade to GitHub-native Dependabot

    Dependabot Preview will be shut down on August 3rd, 2021. In order to keep getting Dependabot updates, please merge this PR and migrate to GitHub-native Dependabot before then.

    Dependabot has been fully integrated into GitHub, so you no longer have to install and manage a separate app. This pull request migrates your configuration from Dependabot.com to a config file, using the new syntax. When merged, we'll swap out dependabot-preview (me) for a new dependabot app, and you'll be all set!

    With this change, you'll now use the Dependabot page in GitHub, rather than the Dependabot dashboard, to monitor your version updates, and you'll configure Dependabot through the new config file rather than a UI.

    If you've got any questions or feedback for us, please let us know by creating an issue in the dependabot/dependabot-core repository.

    Learn more about migrating to GitHub-native Dependabot

    Please note that regular @dependabot commands do not work on this pull request.

    dependencies 
    opened by dependabot-preview[bot] 1
  • Create separate repository for hasgo examples

    Create separate repository for hasgo examples

    Create a seperate repository for examples, so that people can add cool snippets of their code to the repo. (A collection of examples + tutorials etc?)

    exploratory 
    opened by DylanMeeus 1
  • Difference function

    Difference function

    The \ function is list difference (non-associative). In the result of xs \ ys, the first occurrence of each element of ys in turn (if any) has been removed from xs.

    (\\) :: Eq a => [a] -> [a] -> [a] infix 5 
    
    enhancement hacktoberfest 
    opened by DylanMeeus 0
  • Transpose()

    Transpose()

    The transpose function transposes the rows and columns of its argument. For example,

    transpose [[1,2,3],[4,5,6]] [[1,4],[2,5],[3,6]]

    If some of the rows are shorter than the following rows, their elements are skipped:

    transpose [[10,11],[20],[],[30,31,32]] [[10,20,30],[11,31],[32]]

    opened by DylanMeeus 0
Releases(2.0.0)
Owner
Dylan Meeus
Go | Linux | Vim | Coffee
Dylan Meeus
A simple Cron library for go that can execute closures or functions at varying intervals, from once a second to once a year on a specific date and time. Primarily for web applications and long running daemons.

Cron.go This is a simple library to handle scheduled tasks. Tasks can be run in a minimum delay of once a second--for which Cron isn't actually design

Robert K 212 Sep 18, 2022
Set of functions/methods that will ease GO code generation

Set of functions/methods that will ease GO code generation

Matheus Leonel Balduino 1 Dec 1, 2021
Some convenient string functions.

str Some convenient string functions. What This package containsa couple of functions to remove duplicates from string slices and optionally sort them

Grimdork.net 1 Dec 27, 2021
Go-fn Boilerplate for Web Functions

alya-go-fn-boilerplate Go-fn Boilerplate for Web Functions This projects aiming to create a deployment ready go skeleton webserver for fast developmen

Alper Reha 0 Feb 5, 2022
This package provides simple graph to execute functions in a group

Introduction This package provides simple graph to execute functions in a group.

Sujit Baniya 9 Jul 22, 2022
golang long polling library. Makes web pub-sub easy via HTTP long-poll server :smiley: :coffee: :computer:

golongpoll Golang long polling library. Makes web pub-sub easy via an HTTP long-poll server. New in v1.1 Deprecated CreateManager and CreateCustomMana

J Cuga 607 Sep 18, 2022
PHP functions implementation to Golang. This package is for the Go beginners who have developed PHP code before. You can use PHP like functions in your app, module etc. when you add this module to your project.

PHP Functions for Golang - phpfuncs PHP functions implementation to Golang. This package is for the Go beginners who have developed PHP code before. Y

Serkan Algur 52 Aug 26, 2022
YoMo 45 Aug 25, 2022
Package iter provides generic, lazy iterators, functions for producing them from primitive types, as well as functions and methods for transforming and consuming them.

iter Package iter provides generic, lazy iterators, functions for producing them from primitive types, as well as functions and methods for transformi

Matthew Toohey 25 Aug 19, 2022
A wrapper for exposing a shared endpoint for Google Cloud Functions in go. API styled after Node.JS firebase-functions package.

firebase-fx A wrapper for Google Cloud Functions that simplifies the deployment of serverless applications. Meant to expose a similar API to the Fireb

Cleanflo Water Tech 5 May 18, 2022
Data structure and algorithm library for go, designed to provide functions similar to C++ STL

GoSTL English | ็ฎ€ไฝ“ไธญๆ–‡ Introduction GoSTL is a data structure and algorithm library for go, designed to provide functions similar to C++ STL, but more p

stirlingx 714 Sep 23, 2022
Zero allocation Nullable structures in one library with handy conversion functions, marshallers and unmarshallers

nan - No Allocations Nevermore Package nan - Zero allocation Nullable structures in one library with handy conversion functions, marshallers and unmar

Andrey Kuzmin 56 Aug 31, 2022
Go tool for generating sql scanners, sql statements and other helper functions

sqlgen generates SQL statements and database helper functions from your Go structs. It can be used in place of a simple ORM or hand-written SQL. See t

drone.io 183 Sep 4, 2022
Common juju errors and functions to annotate errors. Based on juju/errgo

errors import "github.com/juju/errors" The juju/errors provides an easy way to annotate errors without losing the original error context. The exporte

Juju 1.3k Sep 22, 2022
Go library containing a collection of financial functions for time value of money (annuities), cash flow, interest rate conversions, bonds and depreciation calculations.

go-finance Go library containing a collection of financial functions for time value of money (annuities), cash flow, interest rate conversions, bonds

Alejandro Pedraza 142 Sep 19, 2022
golang OpenGL helper functions

glh: golang OpenGL helpers This package contains a number of functions useful for applications using OpenGL. Code Reference Features Textures and Text

go-gl legacy 22 Apr 8, 2022
A safe way to execute functions asynchronously, recovering them in case of panic. It also provides an error stack aiming to facilitate fail causes discovery.

Async Provides a safe way to execute functions asynchronously, recovering them in case of panic. It also provides an error stack aiming to facilitate

Studio Sol Comunicaรงรฃo Digital Ltda 113 Sep 16, 2022
Hunch provides functions like: All, First, Retry, Waterfall etc., that makes asynchronous flow control more intuitive.

Hunch Hunch provides functions like: All, First, Retry, Waterfall etc., that makes asynchronous flow control more intuitive. About Hunch Go have sever

null 88 Sep 16, 2022
Run functions in parallel :comet:

Parallel fn Run functions in parallel. Limit the number of goroutines running at the same time. Installation go get -u github.com/rafaeljesus/parallel

Rafael Jesus 33 Mar 5, 2022
Project Flogo is an open source ecosystem of opinionated event-driven capabilities to simplify building efficient & modern serverless functions, microservices & edge apps.

Project Flogo is an Open Source ecosystem for event-driven apps Ecosystem | Core | Flows | Streams | Flogo Rules | Go Developers | When to use Flogo |

TIBCO Software Inc. 2.1k Sep 27, 2022