Skip to content

Instantly share code, notes, and snippets.

@arnolddevos
Last active August 29, 2015 14:06
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 arnolddevos/cb30c9167425e53bff7a to your computer and use it in GitHub Desktop.
Save arnolddevos/cb30c9167425e53bff7a to your computer and use it in GitHub Desktop.
some sort of monad defined in terms of a sort of fold
package thing
import scala.language.higherKinds
trait Thing[+T, Context[_]] { parent =>
def foldish[S](s0: S)(f: (S, T) => Context[S]): Context[S]
def map[U](g: T => U) = new Thing[U, Context] {
def foldish[S](s0: S)(f: (S, U) => Context[S]) =
parent.foldish(s0)((s, t) => f(s, g(t)))
}
def flatMap[U](g: T => Thing[U, Context]) = new Thing[U, Context] {
def foldish[S](s0: S)(f: (S, U) => Context[S]) =
parent.foldish(s0)((s, t) => g(t).foldish(s)(f))
}
}
object Thing {
def constant[T, Context[_]](t: T) = new Thing[T, Context] {
def foldish[S](s0: S)(f: (S, T) => Context[S]): Context[S] = f(s0, t)
}
def empty[Context[_]]: Thing[Nothing, Context] = ??? // can't define an empty Thing, unlike scalaz.Foldable
def emptyOfT[T, Context[_]]: Thing[T, Context] = empty // it is covariant anyway
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment