Hasgo
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 |
Delete |
[a] -> a -> [a] |
β |
β |
β |
Returns the slice with the first occurance of the element deleted. |
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. |
Head |
[a] -> a |
β |
β |
β |
Return the first element |
Init |
[a] -> [a] |
β |
β |
β |
Returns all elements minus the last |
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 |
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 |
Sort |
[a] -> [a] |
β |
β |
|
Returns a sorted slice (original remains unsorted) |
Sum |
[a] -> a |
β |
β |
β |
The sum of elements in the slice |
Tail |
[a] -> [a] |
β |
β |
β |
Returns all elements minus the first |
Take |
[a] -> uint64 -> [a] |
β |
β |
β |
Take N elements from the slice, or all if N exceeds the length. |
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!)