gpt4 book ai didi

haskell - 隐式类型强制?

转载 作者:行者123 更新时间:2023-12-02 06:33:20 26 4
gpt4 key购买 nike

我不明白为什么这个代码类型检查:

error1 :: ErrorT String (ReaderT Int IO) Int
error1 = asks id

仅供引用, asks有这种类型:
asks :: Monad m => (r -> a) -> ReaderT r m a

另一方面,我能够理解,此代码类型检查:
reader1 :: ReaderT Int IO Int
reader1 = asks id
id有类型 a -> a并且有一个 Monad 的实例对于 IO ,因此编译器可以推断类型。这对我来说很清楚。
ErrorT是新类型和 haskell spec状态,(在关于新类型的部分):

... it creates a distinct type that must be explicitly coerced to or from the original type ...



根据我的解释,我应该可以得到与 error1 中相同的类型。 仅限 明确地,有一些类似于这样的强制:
reader2 :: ReaderT Int IO (Either String Int)
reader2 = fmap (\i -> Right i) reader1

error2 :: ErrorT String (ReaderT Int IO) Int
error2 = ErrorT reader2

但是,显然,自从 error1排版检查就好了,我隐藏了一些知识。你能帮我揭开它吗?

运行示例代码所需的导入:
import Control.Monad.Error (ErrorT(ErrorT))
import Control.Monad.Reader (ReaderT, asks)

最佳答案

函数asks由两个类型略有不同的相关模块导出。来自 Control.Monad.Trans.Reader 的版本(transformers 包的一部分),具有问题中给出的类型:

asks :: Monad m => (r -> a) -> ReaderT r m a

但是,使用的版本似乎是 mtl 中的版本。包,来自 Control.Monad.Reader模块,它具有以下更通用的类型:
asks :: MonadReader r m => (r -> a) -> m a

所以示例定义
error1 :: ErrorT String (ReaderT Int IO) Int
error1 = asks id

意思是
MonadReader Int (ErrorT String (ReaderT Int IO))

必须持有。

也由 mtl 定义以下是 MonadReader 的实例:
instance Monad m => MonadReader r (ReaderT r m)
instance (Error e, MonadReader r m) => MonadReader r (ErrorT e m)

有了这些,上面的约束减少到
(Error String, Monad IO)

两者都成立。

关于haskell - 隐式类型强制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26803583/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com