我有一个具有此类型签名的管道:
processFileName :: (MonadResource m, MonadThrow m, PrimMonad m) =>
ConduitT FilePath (MapRow Text) m ()
以下使用它的管道构造函数进行类型检查:
readFnameData2 ::MonadResource m => ConduitT (MapRow Text) FilePath m ()
-> ConduitT (MapRow Text) Void m (Vector (MapRow Text))
readFnameData2 files = files
.| processFileName
.| sinkVector
但是,当我尝试修改它以在Vector
单子中实际返回IO
时,我得到了意外的结果:
readFnameData ::MonadResource m => ConduitT (MapRow Text) FilePath m () -> IO (Vector (MapRow Text))
readFnameData files = do
fNameRows <- files
.| processFileName
.| sinkVector
fNameRows & runConduit
产生错误:
* Couldn't match type `Map Text Text' with `Vector (MapRow Text)'
Expected type: IO (Vector (MapRow Text))
Actual type: IO (MapRow Text)
* In a stmt of a 'do' block: fNameRows & runConduit
In the expression:
do fNameRows <- files .| processFileName .| sinkVector
fNameRows & runConduit
In an equation for `readFnameData':
readFnameData files
= do fNameRows <- files .| processFileName .| sinkVector
fNameRows & runConduit
|
70 | fNameRows & runConduit
| ^^^^^^^^^^^^^^^^^^^^^^
我觉得我这里必定缺少一些基本知识,但不确定要看什么才能揭开谜底。
更新:要在下面详细说明我的第一条评论,我们可以看到中间的ConduitT
错误:
readFnameData3 ::MonadResource m => ConduitT (MapRow Text) FilePath m ()
-> IO (Vector (MapRow Text))
readFnameData3 files = runConduit (readFnameData2 files)
* Couldn't match type `Map Text Text' with `()'
Expected type: ConduitT () Void m (Vector (MapRow Text))
Actual type: ConduitT (MapRow Text) Void m (Vector (MapRow Text))
* In the first argument of `runConduit', namely
`(readFnameData2 files)'
In the expression: runConduit (readFnameData2 files)
In an equation for `readFnameData3':
readFnameData3 files = runConduit (readFnameData2 files)
|
67 | readFnameData3 files = runConduit (readFnameData2 files)
| ^^^^^^^^^^^^^^^^^^^^
这显示ConduitT
的第一个字段的类型不匹配。不确定sinkVector
为什么不为此返回单元类型,因为所有runConduit*
似乎都在该位置具有单位,并且由于它是一个接收器,它不能接受其他有意义的输入,因此我想这应该是()
-尽管不确定为什么Void
并不是更好的选择。
答案 0 :(得分:0)
我可以将中间函数更正为
readFnameData2 ::MonadResource m => ConduitT () FilePath m ()
-> ConduitT () Void m (Vector (MapRow Text))
readFnameData2 files = files
.| processFileName
.| sinkVector
readFnameData3 ::MonadResource m => ConduitT () FilePath m ()
-> m (Vector (MapRow Text))
readFnameData3 files = runConduit (readFnameData2 files)
这里的问题是files
应该具有单位输入类型,可以作为源!
readFnameData ::MonadResource m => ConduitT () FilePath m () -> m (Vector (MapRow Text))
readFnameData files = runConduit $ files .| processFileName .| sinkVector