functor in go
Apr. 29th, 2022 08:13 amsrc
package main
import (
"fmt"
"strconv"
)
type Maybe[A any] interface {
GetOrElse(A) A
}
type Functor[A, B, C any] interface {
Map(func(A) B) C
}
type Some[A any] struct {
V A
}
func (s *Some[A]) GetOrElse(A) A {
return s.V
}
type SomeFunctor[A, B any] Some[A]
func (sa *SomeFunctor[A, B]) Map(op func(a A) B) Maybe[B] { return &Some[B]{op(sa.V)} }
type None[A any] struct{}
func (n *None[A]) GetOrElse(a A) A {
return a
}
type NoneFunctor[A, B any] None[A]
func (sa *NoneFunctor[A, B]) Map(op func(a A) B) Maybe[B] { return &None[B]{} }
func FindBy[X any, U ~[]X](src U, f func(X) bool) Maybe[X] {
for _, v := range src {
if f(v) {
return &Some[X]{v}
}
}
return &None[X]{}
}
func MaybeFunctor[A, B any](x Maybe[A]) Functor[A, B, Maybe[B]] {
switch v := x.(type) {
case *Some[A]:
return &SomeFunctor[A, B]{v.V}
case *None[A]:
return &NoneFunctor[A, B]{}
}
return nil
}
func EqF[X comparable](sent X) func(X) bool { return func(x X) bool { return sent == x } }
func main() {
src := []int{1, 2, 3}
fmt.Println(MaybeFunctor[int, string](FindBy(src, EqF(3))).Map(func(x int) string { return "val:" + strconv.Itoa(x) }).GetOrElse("n/a"))
fmt.Println(FindBy(src, EqF(5)).GetOrElse(-1))
}