Skip to content

Instantly share code, notes, and snippets.

@SimonRichardson
Last active February 2, 2021 14:17
Show Gist options
  • Save SimonRichardson/167f2dd6edec27ba6b8d40d4eebdffc5 to your computer and use it in GitHub Desktop.
Save SimonRichardson/167f2dd6edec27ba6b8d40d4eebdffc5 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
)
// Apply
func A[A, B any](f func(A) B) func(A) B {
return func(a A) B {
return f(a)
}
}
func Arrow[A, B, C any](f func(A) B) func(func(B) C) func(A) C {
return func(g func(B) C) func(A) C {
return func(a A) C {
return g(f(a))
}
}
}
// Compose
func B[A, B, C any](f func(B) C) func(func(A) B) func(A) C {
return func(g func(A) B) func(A) C {
return func(a A) C {
return f(g(a))
}
}
}
// Constant
func K[A any](a A) func(A) A {
return func(_ A) A {
return a
}
}
// Fix
func Y[A any](f func(func(A) A) func(A) A) func(A) A {
type YY func(YY) func(A) A
g := func(h YY) func(A) A {
return func(x A) A {
return (f(h(h))(x))
}
}
return g(g)
}
func main() {
a := func(x int) int {
return x + 1
}
var b int = 1
fmt.Println(A(a)(b))
x := func(x int) int {
return x + 2
}
fmt.Println(Arrow[int, int, int](x)(a)(b))
fmt.Println(B[int, int, int](x)(a)(b))
fact := Y(func(f func(int) int) func(int) int {
return func(x int) int {
if x <= 0 {
return 1
} else {
return x * f(x-1)
}
}
})
fmt.Println(fact(20))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment