Skip to content

Instantly share code, notes, and snippets.

@sgrankin
Created June 17, 2020 03:26
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 sgrankin/480be38c44cf42eb196957ab8457f912 to your computer and use it in GitHub Desktop.
Save sgrankin/480be38c44cf42eb196957ab8457f912 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
)
type Result(type T) struct {
Val T
Err error
}
func Ok(type T)(val T) Result(T) { return Result(T){Val: val} }
func Err(type T)(err error) Result(T) { return Result(T){Err: err} }
// Sadly can't take a T->Result(S) because methods can't add type variables
func (r Result(T)) FlatMap(f func(T) (_ Result(T))) (_ Result(T)) {
if r.Err != nil {
return r
}
return f(r.Val)
}
// (but this *can* be a function!)
func FlatMap(type T, S)(r Result(T), f func(t T) (_ Result(S))) (_ Result(S)) {
if r.Err != nil {
return Err(S)(r.Err)
}
return f(r.Val)
}
func init() {
v := Ok(string)("hello")
fmt.Println(v)
v = v.FlatMap(func(v string) (_ Result(string)) { return Ok("world") })
fmt.Println(v)
v2 := FlatMap(string, int)(v, func(v string) (_ Result(int)) { return Ok(42) })
fmt.Println(v2)
}
// A finagle-like service / filter stack (minus the futures)
type Service(type Req, Rep) func(Req) Rep
type Filter(type Req, Req2, Rep2, Rep) func(x Service(Req2, Rep2)) Service(Req, Rep)
func TracingFilter(type Req, Rep)(prefix string) (f Filter(Req, Req, Rep, Rep)) {
return func(s Service(Req, Rep)) (res Service(Req, Rep)) {
return func(req Req) Rep {
fmt.Println(prefix + " begin")
v := s(req)
fmt.Println(prefix + " end")
return v
}
}
}
func init() {
svc := func(x string) string { return "hello " + x }
svc = TracingFilter(string, string)("banana")(svc)
fmt.Println(svc("bob"))
}
func main() {
fmt.Println("·")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment