试图在 haskell 中为这个 monad 定义绑定。如果计算成功,则调用 SCont 延续,如果计算失败,则调用 FCont 延续。
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
试图在 haskell 中为这个 monad 定义绑定。如果计算成功,则调用 SCont 延续,如果计算失败,则调用 FCont 延续。
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
想通了,感谢您的帮助
(xm >>= f) ks kf = xm (\a f' -> fa ks f') kf
您给出的定义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
,您将遵循相同的过程并到达EitherT e (Cont r) a
您的 iso 堆栈。