Open
Description
type Fig[T = ()](wasp: T = ());
func fruit[T, U](monad: Fig[T], fruitctor: T -> U) -> Fig[U] {
Fig(wasp: fruitctor(monad))
}
type Nothing;
type Option[T] = Fig[T | Nothing];
func bind[T, U](opt: Option[T], fruitctor: T -> U) -> Option[U] {
switch opt.wasp {
_: Nothing -> Option(wasp: Nothing),
some: T -> Option(wasp: fruitctor(some))
// we can also now transform our Fig[T | Nothing] into a Fig[T] and call `.fruit` on it
// but can that then become a Fig[T | Nothing] by itself? no reason not to, right?
some: T -> Fig(wasp: some).fruit(fruitctor)
// we can also do the same for Nothing, by going from a Fig[()] to a Fig[Nothing]
// with .fruit() and then to a Fig[T | Nothing]
_: Nothing -> Fig.fruit(x -> Nothing),
}
}
// now for the serious impl?
type Monadic[T = ()](T = ());
func bind[T, U](m: Monadic[T], f: T -> U) -> Monadic[U] {
Monadic(m.0.f())
}
type Nothing;
type Maybe[T] = Monadic[T | Nothing];
func bind[T, U](m: Maybe[T], f: T -> U) -> Maybe[T] {
switch m.0 {
_: Nothing -> Monadic.bind(_ -> Nothing),
_: Nothing -> Monadic(Nothing)
inner: T -> Monadic(inner).bind(f),
}
}
// how are the two bind functions differentiated?
Metadata
Metadata
Assignees
Labels
No labels