Haskell 在Either反同构的实现中,我在哪里引入了额外的一元结构?

Haskell 在Either反同构的实现中,我在哪里引入了额外的一元结构?,haskell,Haskell,我正试图从第一原则-26.3-ex5编写Haskell编程的解决方案 问题是要编写一个版本的任意一个反同构,它在monad transformer变体either上工作。功能的类型应为: eitherT :: Monad m => (e -> m c) -> (a -> m c) -> EitherT e m a -> m c 以下是本书中定义的EITHER新类型,以供参考: newtype EitherT e m a = --why does the bo

我正试图从第一原则-26.3-ex5编写Haskell编程的解决方案

问题是要编写一个版本的任意一个反同构,它在monad transformer变体either上工作。功能的类型应为:

eitherT :: Monad m => (e -> m c) -> (a -> m c) -> EitherT e m a -> m c
以下是本书中定义的EITHER新类型,以供参考:

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)}
此外,我还有一个正在工作的
实例Monad m=>Monad(EitherT e m)
,以及前面的Functor和Applicative

问题陈述中给出的类型签名表明我需要使用m的一元功能,或者可能使用(EitherT e m)。然而,我写了一个只使用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)

  • fe-fa::e-a->c

  • fmap(或fe-fa)::m(或e-a)->m-c

  • fmap(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->mc)
    的形式,我的解决方案是有效的

    更改eitherT的类型签名以反映允许代码编译的类型。我推理中的具体缺陷在第2步中,应该是:

  • fe-fa::e-a->m-c

  • 要使用原始签名实现,请参见(重要)组合器
    join::m(ma)->ma