具有“真实”返回功能的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

上一篇: A monad with a "real" return function

下一篇: Haskell monad: etymology versus meaning?