具有“真实”返回功能的monad
  一个常见的初学者的错误是看到return并认为它是一个语言关键字,它以返回值退出当前函数。  当然,我们知道这不是它所做的。  但我想知道......我们能否真的做出这样的功能?  纯粹为了论证的缘故,在这一点上。 
  看来我们正在寻找一些具有功能的monad Foo 
exit :: x -> Foo x
  这将中止其余的计算并立即返回x 。 
这样的事情是可以修复的吗? 如果可以构建,它会有用吗? 这是一种理智的尝试吗?
  是的,在Cont单元中是可能的。  Cont的定义如下: 
newtype Cont r a = Cont {runCont :: (a -> r) -> r}
instance Monad (Cont r) where
    return a = Cont ($ a)
    m >>= k = Cont $ c -> runCont m $ a -> runCont (k a) c
  现在我们可以创建如下exit : 
exit = Cont . const
  事实上,你可以在几乎任何单子(例如,你可以做到这一点在做Either单子,但是不在State单子)。  然而, Cont monad是所有monad的母亲:http://blog.sigfpe.com/2008/12/mother-of-all-monads.html 
当然这是可行的。 它甚至已经在标准库中。 你只需要一个稍微清晰的类型签名。
import Control.Monad
exit :: a -> Either a b
exit = Left
main = print $ do
    x <- Right 5
    exit "foo"
    error "this is a good place to crash"
重要的是要注意的是,救助时给出的类型不是免费的 - 它必须与Either的类型相匹配。
看来你可以实现这一点:
data Foo e x =
  Next x |
  Done e
instance Monad (Foo e) where
  return = Next
  (Next x) >>= f = f x
  (Done e) >>= f = Done e
exit :: e -> Foo e x
exit = Done
run :: Foo x x -> x
run (Next x) = x
run (Done x) = x
  注意单子如何有一个额外的类型参数;  我认为这是可以避免的。  基本上Foo ex产生一个x并且将“最终”产生一个e 。  请注意, run功能需要两种类型匹配;  你也可以同样要求run只在exit被称为某处或其他几种可能性之一时才起作用。 
所以,是的,你可以构建这个,不,它不是特别有用的AFAIK。
链接地址: http://www.djcxy.com/p/43363.html