使用多个变量键入类约束

时间:2016-02-17 17:43:47

标签: haskell typeclass

我很难掌握Monad Reader函数的以下类型类约束,它接收多个变量,

id

如何正确理解类型类约束?哪一个是类型构造函数,local :: MonadReader r m => (r -> r) -> m a -> m a r或两者? (来自m部分,它建议类型构造函数为m a)。

与例如绑定函数相比,其中类型类约束仅允许单个参数;

m

与上面的本地函数不同,很明显且很容易理解bind函数的类型类约束需要类型构造函数(>>=) :: Monad m => m a -> (a -> m b) -> m b 作为Monad实例。

1 个答案:

答案 0 :(得分:2)

在这些情况下,最好在这里查看课程(MonadReader)。

你会发现这个:

class Monad m => MonadReader r m | m -> r where

还有更多。

所以这里m是一些monad,r将是你读的东西(MonadReader是一个所谓的monad-transformer ...好吧不太好 - 这是班级这对所有变形金刚来说都很常见 - ReaderT是变形金刚......但解释真的太可怕了......对不起)

local用于更改您读取的内容(我喜欢将其视为配置或环境) - r->r部分 - 给您一个monad m中的计算将进行此更改。

如果你在文档中阅读,甚至有一个如何使用它的例子:

calculateContentLen :: Reader String Int
calculateContentLen = do
    content <- ask
    return (length content);

-- Calls calculateContentLen after adding a prefix to the Reader content.
calculateModifiedContentLen :: Reader String Int
calculateModifiedContentLen = local ("Prefix " ++) calculateContentLen

main = do
    let s = "12345";
    let modifiedLen = runReader calculateModifiedContentLen s
    let len = runReader calculateContentLen s
    putStrLn $ "Modified 's' length: " ++ (show modifiedLen)
    putStrLn $ "Original 's' length: " ++ (show len)

正如您所看到的,local用于在字符串前面添加"Prefix "

请注意,此示例中的monad m IO - 它是Identity(基本上没有 - 它有没有效果)

(我希望可以复制并粘贴它......如果没有,请告诉我或删除它)