Skip to content

Instantly share code, notes, and snippets.

@fogfish
Created March 29, 2022 13:24
Show Gist options
  • Save fogfish/2789a73bde80e3386c17809718c735ef to your computer and use it in GitHub Desktop.
Save fogfish/2789a73bde80e3386c17809718c735ef to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"strconv"
)
//
//
func filter[A any](f func(A) bool, a A) A {
none := *new(A)
if !f(a) {
return none
}
return a
}
func fmap[A, B any](f func(A) B, a A) B {
return f(a)
}
//
//
func filterF[A any](f func(A) bool) func(A) A {
return func(a A) A { return filter(f, a) }
}
func fmapF[A, B any](f func(A) B) func(A) B {
return func(a A) B { return fmap(f, a) }
}
//
//
func dot[A, B, C any](f func(A) B, g func(B) C) func(A) C {
return func(a A) C { return g(f(a)) }
}
//
//
func dotJ[A, B, C any](f func(A) B, g func(B) C, fs ...func(C) C) func(A) C {
return func(a A) C {
x := g(f(a))
for _, y := range fs {
x = y(x)
}
return x
}
}
//
//
type Map[A, B, C any] func(A) B
func (f Map[A, B, C]) fmap(g func(B) C) func(A) C {
return func(a A) C {
return g(f(a))
}
}
//
//
func lt10(x int) bool { return x < 10 }
func like(x string) string { return fmt.Sprintf("+(%v)", x) }
func main() {
x := 1
//
y := fmap(like, fmap(like, fmap(strconv.Itoa, filter(lt10, x))))
fmt.Printf("==> %s\n", y)
//
f := filterF(lt10)
g := fmapF(strconv.Itoa)
h := fmapF(like)
fmt.Printf("==> %s\n", h(h(g(f(x)))))
//
w := dot(dot(dot(f, g), h), h)
fmt.Printf("==> %s\n", w(x))
//
p := dotJ(f, g, h, h)
fmt.Printf("==> %s\n", p(x))
//
z := Map[int, string, string](
Map[int, string, string](
Map[int, int, string](
f,
).fmap(g),
).fmap(h),
).fmap(h)
fmt.Printf("==> %s\n", z(x))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment