haskell - Rebinding do notation for indexed monads -
i following conor mcbride's "kleisli arrows of outrageous fortune" paper , i've posted implementation of code here. briefly, defines following types , classes:
type :-> b = forall . -> b class ifunctor f imap :: (a :-> b) -> (f :-> f b) class (ifunctor m) => imonad m skip :: :-> m bind :: (a :-> m b) -> (m :-> m b) data (a := i) j v :: -> (a := i)
then defines 2 types of binds, latter of uses (:=)
restrict initial index:
-- conor mcbride's "demonic bind" (?>=) :: (imonad m) => m -> (a :-> m b) -> m b (?>=) = flip bind -- conor mcbride's "angelic bind" (>>=) :: (imonad m) => m (a := j) -> (a -> m b j) -> m b m >>= f = bind (\(v a) -> f a) m
the latter bind works fine rebinding do
notation use indexed monads rebindablesyntax
extension, using following corresponding definitions return
, fail
:
return :: (imonad m) => -> m (a := i) return = skip . v fail :: string -> m fail = error
... problem cannot former bind (i.e. (?>=)
) work. tried instead defining (>>=)
, return
be:
(>>=) :: (imonad m) => m -> (a :-> m b) -> m b (>>=) = (?>=) return :: (imonad m) => :-> m return = skip
then created data type guaranteed inhabit specific index:
data unit unit :: unit ()
but when try rebind do
notation using new definitions (>>=)
, return
, not work, demonstrated in following example:
-- without notation test1 = skip unit >>= \unit -> skip unit -- notation test2 = unit <- skip unit skip unit
test1
type-checks, test2
not, weird, since thought rebindablesyntax
did let do
notation desugar test2
test1
, if test1
type-checks, why not test2
? error is:
couldn't match expected type `t0 -> t1' actual type `a0 :-> m0 b0' expected type: m0 a0 i0 -> (t0 -> t1) -> m unit () actual type: m0 a0 i0 -> (a0 :-> m0 b0) -> m0 b0 i0 in stmt of 'do' block: unit <- skip unit in expression: { unit <- skip unit; skip unit }
the error remains when use explicit forall
syntax instead of :->
type operator.
now, know there problem using "demonic bind", can't define (>>)
, still wanted see how far go it. can explain why cannot ghc desugar "demonic bind", when type-check?
iiuc, ghc desugarer runs after typechecker (source). explains why situation observe theoretically possible. typechecker has special typing rules do-notation, , may inconsistent typechecker desugarred code.
of course, it's reasonable expect them consistent, recommend filing ghc bug.
Comments
Post a Comment