Purescript中的读者Monad

时间:2015-03-17 10:34:25

标签: purescript reader-monad

我正在玩Purescript中的Reader monad,我遇到了一个奇怪的行为。我不知道是不是因为我对这个monad缺乏理解,或者我错过了其他的东西。

这是我的代码:

type Level = Number
type Doc = Reader Level String

renderLine :: String -> Level -> String
renderLine s 0 = s
renderLine s l = "\t" ++ (renderLine s (l - 1))

line :: String -> Doc
line s = do
    level <- ask
    return (renderLine s level)

这没关系并且会编译。然而,在此之前,我在我的功能行中尝试了一些更简单的东西:

line :: String -> Doc
line s = do
    level <- ask
    return "Hello Reader monad"

它不会编译,尽管事实上(renderLine s level)和&#34; Hello Reader monad&#34;具有相同的类型。它会给我这个错误: &#34;没有为Control.Monad.Reader.Class.MonadReader发现实例u14555(Control.Monad.Reader.Trans.ReaderT Prim.Number Control.Monad.Identity.Identity)&#34;

我确定我错过了什么,但我不知道是什么。

1 个答案:

答案 0 :(得分:7)

该错误的更易读的版本是:

No instance found for MonadReader ? (Reader Number)

我认为这里的问题是由于PureScript中缺少功能依赖性 - 在Haskell中MonadReader类被定义为MonadReader r m | m -> r所以rm决定,但我们不能在PureScript中这样做。

我怀疑它在前一种情况下起作用的原因而不是后一种情况level的类型在调用Level时与renderLine统一,这意味着{{1}因此,必须r

由于你在后一种情况下没有对Level做任何事情,因此类型变量不统一,而且错误的来源是因为确实没有实例level未知时的MonadReader。