-1

试图在 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
4

2 回答 2

1

想通了,感谢您的帮助

(xm >>= f) ks kf = xm (\a f' -> fa ks f') kf

于 2016-03-30T15:17:48.533 回答
1

您给出的定义SCont对我来说很奇怪:成功的延续怎么会以失败的延续为论据?另外,给定你returnbind,看起来失败的线程一直沿着调用树向下传递,并且......应用于成功的线程,以防你返回。

我希望“双桶延续 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 堆栈。

于 2016-03-30T23:32:43.000 回答