haskell - 在实现 EitherT 变态时,我在哪里引入了额外的一元结构?
问题描述
我正在尝试从第一原理 - 26.3 - Ex 5 编写 Haskell 编程的解决方案。
问题是编写一个适用于 monad 转换器变体 EitherT 的变态变体的一个版本。函数的类型应该是:
eitherT :: Monad m => (e -> m c) -> (a -> m c) -> EitherT e m a -> m c
作为参考,这里是本书中定义的 EitherT 新类型:
newtype EitherT e m a = --why does the book use e a for the type parameters instead of a b? Error type?
EitherT {runEitherT :: m (Either e a)}
此外,我有一个工作instance Monad m => Monad (EitherT e m)
,以及 Functor 和 Applicative 在它之前。
问题陈述中给出的类型签名表明我需要使用 m 的 Monadic 功能,或者可能是 (EitherT em)。但是,我编写了一个仅使用我认为可行的 fmap 的版本:
eitherT :: Monad m => (e -> m c) -> (a -> m c) -> EitherT e m a -> m c
eitherT fe fa = fmap (either fe fa) . runEitherT
这不编译。具体来说,编译器抱怨我构造了无限类型 c ~ mc (下面的完整输出)。我将把它作为另一个线索,表明这个问题应该用一些单子函数来解决。但是,我想了解我的方法在该结构中添加的位置。到目前为止,我不能。
这是我编写代码的理由:
runEitherT :: EitherT e m a -> m (Eihter e a)
either fe fa :: Either e a -> c
fmap (either fe fa) :: m (Either e a) -> m c
fmap (either fe fa) . runEitherT :: EitherT e m a -> m c
这似乎与类型应该是完全匹配的eitherT fe fa
。
有人可以指出我哪里出错了吗?
完整的错误信息:
Haskell> :l EitherT.hs
[1 of 1] Compiling EitherT ( EitherT.hs, interpreted )
EitherT.hs:36:17: error:
* Occurs check: cannot construct the infinite type: c ~ m c
Expected type: EitherT e m a -> m c
Actual type: EitherT e m a -> m (m c)
* In the expression: fmap (either fe fa) . runEitherT
In an equation for `eitherT':
eitherT fe fa = fmap (either fe fa) . runEitherT
* Relevant bindings include
fa :: a -> m c (bound at EitherT.hs:36:12)
fe :: e -> m c (bound at EitherT.hs:36:9)
eitherT :: (e -> m c) -> (a -> m c) -> EitherT e m a -> m c
(bound at EitherT.hs:36:1)
|
36 | eitherT fe fa = fmap (either fe fa) . runEitherT
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed, no modules loaded.
解决方案
好吧,我在查看问题的格式时找到了答案。如果它对其他人有帮助,这里是:
如果 和 的类型是fe
形式fa
而(a -> c)
不是(a -> m c)
.
更改 anyT 的类型签名以反映允许代码编译的情况。我推理中的具体缺陷在步骤 2 中,应该是:
either fe fa :: Either e a -> m c
推荐阅读
- raspberry-pi3 - 控制从网页连接到树莓派的设备
- facebook - Instant Article Builder - 如何选择文章内容的两个区域/元素?
- c# - UWP 应用程序中的 SEHException - 尝试为 SDK 加载 DLL
- angular - 错误 ReferenceError:配置未定义 Angular 7
- python - Python:在for循环中更新父级
- android - 数据不显示在列表视图中
- binary-tree - 给定完整二叉树的后序遍历,找到它的中序遍历
- python - 在python中生成一个长度为l的三进制数列表,可以逐位查询
- android - Android 更新后改造崩溃
- android - 工具栏不显示