Purescript中的读者Monad

Tho*_*C__ 2 reader-monad purescript

我正在玩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)
Run Code Online (Sandbox Code Playgroud)

这没关系,会编译.不过,在此之前我在我的功能行中尝试了一些更简单的方法:

line :: String -> Doc
line s = do
    level <- ask
    return "Hello Reader monad"
Run Code Online (Sandbox Code Playgroud)

尽管(renderLine s level)和"Hello Reader monad"具有相同的类型,但它不会编译.它会抛出这个错误:"找不到Control.Monad.Reader.Class.MonadReader u14555(Control.Monad.Reader.Trans.ReaderT Prim.Number Control.Monad.Identity.Identity)的实例"

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

gb.*_*gb. 7

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

No instance found for MonadReader ? (Reader Number)

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

我怀疑它在前者的情况下工作,而不是后者是类型的原因level正在用统一Level的调用renderLine,这意味着r因此也必须是Level.

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