我正在尝试从第一原理-26.3-实现例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或可能的(EitherT e m)的Monadic功能。但是,我写了一个只使用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.
    

    最佳答案

    好吧,我在查看问题的格式时就找到了答案。万一它对其他人有帮助,这里是:

    如果fefa的类型为(a -> c)而不是(a -> m c),则我的解决方案有效。

    更改anyT的类型签名以反射(reflect)出可以编译代码的方式。我的推理中的特定缺陷在于步骤2,该步骤应显示为:

  • either fe fa :: Either e a -> m c
  • 关于haskell - 在实现EitherT同形异像的过程中,我在哪里引入了额外的单子(monad)结构?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56998130/

    10-13 00:30