Skip to content

Instantly share code, notes, and snippets.

@btrepp
Created April 6, 2017 00:26
Show Gist options
  • Save btrepp/d0d04e1ad90d7e5e435a09f01fed76a3 to your computer and use it in GitHub Desktop.
Save btrepp/d0d04e1ad90d7e5e435a09f01fed76a3 to your computer and use it in GitHub Desktop.
ReaderT monad in FSharp
//A generic container class that ships the type class along with it.
//Used to defined functors of types
type Generic<'T, 'TypeClass when 'TypeClass : (new : unit -> 'TypeClass)> = interface end
//Definition of a monad. Like the functor class, this can be created with new to get the bind/return methods for that
//Monad type
type [<AbstractClass>] MonadClass<'MonadClass when 'MonadClass :> MonadClass<'MonadClass>
and 'MonadClass : (new: unit -> 'MonadClass)>() =
abstract Return<'R> : ('R) -> Generic<'R,'MonadClass>
abstract Bind<'a,'b> : ('a->Generic<'b,'MonadClass>) -> Generic<'a,'MonadClass> -> Generic<'b,'MonadClass>
type ReaderT<'e,'a,'m when 'm :> MonadClass<'m> and 'm : (new:unit->'m)> = ReaderT of ('e -> Generic<'a,'m>)
with interface Generic<'a,ReaderTMonad<'e,'m>>
and ReaderTMonad<'e,'m when 'm :> MonadClass<'m> and 'm :(new:unit -> 'm)>()=
inherit MonadClass<ReaderTMonad<'e,'m>>()
override x.Return<'a> (a:'a) :Generic<'a,ReaderTMonad<'e,'m>> = ReaderT.return' a :> Generic<'a,ReaderTMonad<'e,'m>>
override x.Bind<'a,'b> (f:'a->Generic<'b,ReaderTMonad<'e,'m>>)
(m:Generic<'a,ReaderTMonad<'e,'m>>)
: Generic<'b,ReaderTMonad<'e,'m>>=
let mi = m :?> _
let fi = fun a -> f a :?> _
ReaderT.bind(fi ,mi) :> _
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment