在我的库中,我想向文档中的用户公开底层单子状态的名称,但是我不希望他们能够将其拆开-我想制作一个黑匣子。
因此,我从使用以下类型别名的完整代码开始:
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] 删除。
我来说两句