У меня есть канал с такой подписью типа:
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
не лучший вариант.