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