Haskell:将类型别名更改为新类型会产生错误

范伯伦登克

在我的库中,我想向文档中的用户公开底层单子状态的名称,但是我不希望他们能够将其拆开-我想制作一个黑匣子。

因此,我从使用以下类型别名的完整代码开始:

type Surge e c z m = ErrorT (Failure z) (ReaderT (SurgeChan e c) (Parser' ByteString m))

然后,为了使其更强大,我将其更改为newtype并启用了GeneralizedNewtypeDeriving

newtype Surge e c z m a = Surge
    { runSurge' :: ErrorT (Failure z) (ReaderT (SurgeChan e c) (Parser' ByteString m)) a }
    deriving (Monad, Applicative, Functor)

我还有一些其他的代码需要像这样调整:

res <- flip St.evalStateT prod . flip runReaderT sc . runErrorT $ pipeline

==>

res <- flip St.evalStateT prod . flip runReaderT sc . runErrorT . runSurge' $ pipeline

不幸的是,由于某种原因,在我进行type->newtype更改后,并非所有代码都会进行类型检查这部分代码特别是:

{-# INLINE decodeAndHandlePacket #-}
decodeAndHandlePacket
    = handlePacket ~< errorP (lift.lift.liftM (first DecodeFailure) . decodeGet $ decodePacket)

...现在无法进行类型检查,出现了很长的错误,而以前却没有:

src/Surge/Internal.hs:101:27:
    Couldn't match type ‘ErrorT
                           (Failure z0) (t0 (St.StateT (Producer ByteString m0 x0) m0))’
                  with ‘Surge e c z m’
    Expected type: Proxy a' a () p' (Surge e c z m) ByteString
      Actual type: Proxy
                     a'
                     a
                     ()
                     p'
                     (ErrorT
                        (Failure z0) (t0 (St.StateT (Producer ByteString m0 x0) m0)))
                     ByteString
    Relevant bindings include
      decodeAndHandlePacket :: Proxy a' a () p' (Surge e c z m) ()
        (bound at src/Surge/Internal.hs:100:5)
      handleCommand :: Handler c p' (Surge e c z m)
        (bound at src/Surge/Internal.hs:84:7)
      handleEvent :: Handler e p' (Surge e c z m)
        (bound at src/Surge/Internal.hs:84:7)
      handlePacket :: Handler ByteString p' (Surge e c z m)
        (bound at src/Surge/Internal.hs:84:7)
      stage :: Stage ByteString p' e c (Surge e c z m)
               -> Producer ByteString (Surge e c z m) ()
        (bound at src/Surge/Internal.hs:84:1)
    In the second argument of ‘(~<)’, namely
      ‘errorP
         (lift . lift . liftM (first DecodeFailure) . decodeGet
          $ decodePacket)’
    In the expression:
      handlePacket
      ~<
        errorP
          (lift . lift . liftM (first DecodeFailure) . decodeGet
           $ decodePacket)

我不知道该怎么做。双方看起来与我相同。

完整代码可从http://lpaste.net/109472获得谢谢。

汤姆·埃利斯

你要

decodeAndHandlePacket
        = handlePacket ~< hoist Surge (errorP (lift.lift.liftM (first DecodeFailure) . decodeGet $ decodePacket))

请注意,对的调用的返回类型errorP

Proxy a'0 a0 () p' (ErrorT (Failure ...)) ByteString

并且您要用新类型替换第五个参数,即

Proxy a'0 a0 () p' (Surge e c z m) ByteString

这个新类型是monad(类型构造函数),您需要hoist将动作(ErrorT (Failure ...))放入(Surge ...)monad中。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

类型别名错误

来自分类Dev

使用递归类型别名会产生循环引用错误

来自分类Dev

在DB2中将数据类型从DateTime更改为Time会产生错误

来自分类Dev

在DB2中将数据类型从DateTime更改为Time会产生错误

来自分类Dev

Haskell中的多态类型别名

来自分类Dev

返回与类型别名不匹配的函数不会产生错误-为什么?

来自分类Dev

类型别名与类型相同

来自分类Dev

Typeof / instanceof类型别名

来自分类Dev

std :: bind与类型别名

来自分类Dev

Rust中的类型别名

来自分类Dev

快速扩展类型别名

来自分类Dev

Scala中的类型别名

来自分类Dev

类型别名的伴随对象

来自分类Dev

条件类型别名定义

来自分类Dev

如何创建类型别名

来自分类Dev

通用函数类型别名

来自分类Dev

如何检测类型别名?

来自分类Dev

键值对的TypeScript类型别名

来自分类Dev

TypeScript中的类型别名

来自分类Dev

Scala 中的类型别名

来自分类Dev

Scala类型标签和类型别名

来自分类Dev

从类型别名转换为原始类型

来自分类Dev

如何从类型别名确定类型?

来自分类Dev

类型别名和类似类型

来自分类Dev

如何从类型别名提取类型实参和类型参数引用其他类型别名?

来自分类Dev

如何从类型别名提取类型实参和类型参数引用其他类型别名?

来自分类Dev

Java printf提供“将类型更改为对象”错误

来自分类Dev

将变量的类型更改为 Observable 后的错误(Angular 7)

来自分类Dev

使用GameKit时,将源文件类型更改为Objective-C ++会导致链接器错误