尝试在haskell中为此monad定义bind。 如果计算成功,则调用SCont continuation,如果失败,则调用FCont continuation。
type M a = SCont a -> FCont -> Answer
type SCont a = a -> FCont -> Answer
type FCont = () -> Answer
result :: a -> M a
result x ks kf = ks x kf
(>>=) :: M a -> (a -> M b) -> M b
答案 0 :(得分:1)
想出来,谢谢你试图帮助
(xm>> = f)ks kf = xm(\ a f' - > f a ks f')kf
答案 1 :(得分:1)
你给SCont
的定义对我来说很奇怪:成功的延续如何将失败作为一个论证?另外,给定return
和bind
,看起来失败的一个线程一直沿着调用树进行操作,并且......如果你遇到了返回,则应用于成功。
我希望'双管延续Monad'的定义如下:
module SFCont where
import Control.Monad
newtype SFCont r a = SFCont { sfCont :: SCont r a -> FCont r a -> r }
type SCont r a = a -> r
type FCont r a = r
instance Functor (SFCont r) where
fmap f (SFCont c) = SFCont $ \ ks -> c (ks . f)
-- this will be obtained from the definition of the `Monad` instance
instance Applicative (SFCont r) where
pure = return
(<*>) = ap
instance Monad (SFCont r) where
return a = SFCont $ const . ($ a)
m >>= f = SFCont $ \ ks kf -> sfCont m (\ a -> sfCont (f a) ks kf) kf
通过推理同构并注意到:
我们可以找到一种系统的方法来定义它(以及它的表兄,其中失败可以采用错误类型e
的元素)。
SCont r a -> FCont r a -> r ~{ unfolding SCont, FCont }
(a -> r) -> r -> r ~{ r iso (() -> r) }
(a -> r) -> (() -> r) -> r ~{ uncurrying }
((a -> r), (() -> r)) -> r ~{ ((a -> r), (b -> r)) iso (Either a b -> r) }
(Either a () -> r) -> r ~{ Either a () iso Maybe a }
(Maybe a -> r) -> r ~{ folding MaybeT, Cont }
MaybeT (Cont r) a
现在,我们可以通过写下这个iso来利用现有的实例:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module SFCont where
import Data.Functor.Identity
import Control.Monad
import Control.Monad.Trans.Maybe
import Control.Monad.Trans.Cont
newtype SFCont r a = SFCont { sfCont :: SCont r a -> FCont r a -> r }
type SCont r a = a -> r
type FCont r a = r
newtype SFCont' r a = SFCont' { sfCont' :: MaybeT (Cont r) a }
deriving (Functor, Applicative, Monad)
to :: SFCont r a -> SFCont' r a
to m = SFCont' $ MaybeT $ ContT $ \ k -> Identity $
sfCont m (runIdentity . k . Just) (runIdentity $ k Nothing)
from :: SFCont' r a -> SFCont r a
from m = SFCont $ \ ks kf -> runIdentity $
(runContT $ runMaybeT $ sfCont' m) (Identity . maybe kf ks)
instance Monad (SFCont r) where
return = from . return
m >>= f = from $ to m >>= to . f
如果失败继续可以采用错误类型e
的元素,那么您将遵循相同的过程并到达您的iso的堆栈EitherT e (Cont r) a
。