Skip to content

Instantly share code, notes, and snippets.

@jordanorelli
Created November 29, 2021 14:04
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 jordanorelli/cb2c14cc4da846237736adedf28bcfb6 to your computer and use it in GitHub Desktop.
Save jordanorelli/cb2c14cc4da846237736adedf28bcfb6 to your computer and use it in GitHub Desktop.
oh is this all it is
package main
import (
"fmt"
"unicode/utf8"
)
type Maybe[T any] struct {
val T
ok bool
}
func (m Maybe[T]) Open() (T, bool) {
return m.val, m.ok
}
func (m Maybe[T]) String() string {
if m.ok {
return fmt.Sprint(m.val)
}
return "None"
}
func New[T any](v T, ok bool) Maybe[T] {
if ok {
return Maybe[T]{val: v, ok: ok}
}
return Maybe[T]{}
}
func None[T any]() Maybe[T] { return Maybe[T]{} }
func NoneOf[T any](v T) Maybe[T] { return Maybe[T]{} }
func Some[T any](v T) Maybe[T] {
return Maybe[T]{
val: v,
ok: true,
}
}
func Bind[X, Y any](f func(X) Y) func(Maybe[X]) Maybe[Y] {
return func(ox Maybe[X]) Maybe[Y] {
if x, ok := ox.Open(); ok {
return Some(f(x))
}
return None[Y]()
}
}
func getCity(name string) (string, bool) {
if name == "Alice" {
return "Chicago", true
}
return "", false
}
func main() {
name := Some("Jordan")
city := None[string]()
// this function doesn't know about the Maybe type but now it does:
count := Bind(utf8.RuneCountInString)
fmt.Printf("Name: %v (%v)\n", name, count(name))
fmt.Printf("City: %v (%v)\n", city, count(city))
alice := "Alice"
bob := "Bob"
fmt.Printf("Alice: %s (%v)\n", alice, count(New(getCity(alice))))
fmt.Printf("Bob: %s (%v)\n", bob, count(New(getCity(bob))))
if n, ok := name.Open(); ok {
fmt.Printf("Name: %s\n", n)
} else {
fmt.Println("no name given")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment