Skip to content

Instantly share code, notes, and snippets.

@aarondl
Last active August 2, 2018 08:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aarondl/9b950373642fcf5072942cf0fca2c3a2 to your computer and use it in GitHub Desktop.
Save aarondl/9b950373642fcf5072942cf0fca2c3a2 to your computer and use it in GitHub Desktop.
Go Generics and Algebraic datatypes
package main
import "fmt"
// Types can also have type arguments (convention is single letter lowercase
// convention could also name this t(type), u, v instead of a, b, c if we wanted)
type Ok a struct {
Value a
}
type Err a struct {
Value a
}
type Result a b union {
Ok a
Err b
}
func main() {
// The following are equivalent due to type inference
var o Ok string = Ok{Value: "string"}
var o = Ok{Value: "string"}
// Invalid, to keep consistency
var o Ok = Ok{Value: "string"}
// We could use := if we wanted here, but we're
// showing how to use the var statement.
var result Result int string
result = getUserCount()
match result {
Ok val:
fmt.Println("there are", val, "users")
Err val:
fmt.Sprintf("error: %s\n", val)
}
}
package main
import "fmt"
type LinkedList a struct {
Head *Node a
Tail *Node a
}
type Node a {
Next *Node a
Prev *Node a
Value a
}
func main() {
// Not sure about how recursive we could get with the inference
ll := LinkedList string {
// The string bit could be inferred
Head: Node string { Value: "hello world" },
}
}
func (l *LinkedList a) Append(value a) {
// Type inference helps us here
newNode := &Node{Value: value}
if l.Tail == nil {
l.Head = newNode
l.Tail = l.Head
return
}
l.Tail.Next = newNode
l.Tail = l.Tail.Next
}
package slicefun
// A type which is a single lowercase letter in place of a real type
// becomes a generic argument
func map(slice []a, fn func(a) a) {
for i := range slice {
slice[i] = fn(slice[i])
}
}
func sort(slice []a, func(a, a) bool) {
...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment