[MLton-user] Extended Basis Library: Suggested change to the MONADP signature

Vesa Karvonen vesa.a.j.k at gmail.com
Thu Apr 5 00:28:39 PDT 2007


On 4/5/07, Geoffrey Alan Washburn <geoffw at cis.upenn.edu> wrote:
>  Vesa Karvonen wrote:
[value restriction]
>      If you are defining a MONADP from scratch, no I don't think it can ever
> be a problem.  However, if you are interested in writing monad transformers,
> say
>
>  functor MkErrorMonad (M : MONAD_CORE) :> MONADP_CORE =
>  struct
>    type 'a monad = ('a option) M.monad
>    fun return x = M.return (SOME x)
>    fun op >>= (aM, f) =
>        M.>>= (aM, fn SOME a => M.>>= (f a, return) | NONE => M.return NONE)

BTW, while trying this I noticed that the subexpression

   M.>>= (f a, return)

should be just

  f a

(IIRC - I don't have the corrected code at this point as I kept editing...)

>    val zero = return NONE
>    fun op <|> (aM, bM) =
>        M.>>= (aM, fn SOME a => return a | NONE => bM)
>  end
>
>  You'll run into problems.  It may be conceivable that the above could be
> rewritten with
>
>      type 'a monad = 'a M.monad option
>
>  but it is either not possible to write bind for this type or my brain has
> called it a day already.

I see.  However, an alternative to having a parameterized zero would be to
simply introduce additional thunking in the monad transformer.  Here is
how it would look like (the following code compiles fine):

functor MkErrorMonad (M : MONAD_CORE) :> MONADP_CORE = struct
   type 'a monad = 'a Option.t M.monad Thunk.t
   fun return x () = M.return (SOME x)
   fun zero () = M.return NONE
   fun op <|> (aM, bM) () =
       M.>>= (aM (),
              fn SOME a => M.return (SOME a)
               | NONE   => bM ())
   fun op >>= (aM, a2bM) () =
       M.>>= (aM (),
              fn SOME a => a2bM a ()
               | NONE   => M.return NONE)
end

So, it seems that it is always possible to work around the value
restriction in this context (which is when implementing MONADP_CORE).

In a sense, even when implementing a monad transformer, you are
implementing a MONADP from scratch, because you get to decide the
type of the resulting monad.

-Vesa Karvonen



More information about the MLton-user mailing list