我正在学习conduit
并希望创建一个处理器,它将从stdin中获取json输入,以某种方式处理它,然后输出到stdout。选择漂亮的印刷作为例子。
现在我想解码json并将其打印出来。但似乎我遇到了Bytestring
类型不匹配的问题。
import Control.Monad.Trans.Resource
import Data.Aeson
import Data.Conduit
import qualified Data.Conduit.Combinators as CC
import Data.Conduit (await, yield, (.|))
import Data.ByteString.Lazy.Char8 as BC
import qualified Data.Conduit.Binary as CB
import Data.JsonStream.Parser hiding ((.|))
import qualified Data.Text as T
import System.IO (stdin, stdout)
jsonParse :: Conduit BC.ByteString IO (T.Text, Value)
jsonParse = doParse parseOutput
where
parseOutput :: ParseOutput (T.Text, Value)
parseOutput = runParser (objectItems value)
doParse :: ParseOutput (T.Text, Value) -> Conduit BC.ByteString IO (T.Text, Value)
doParse out = case out of
ParseYield value newOutput -> do
yield value
doParse newOutput
ParseNeedData cont ->
awaitForever $ \i -> doParse (cont i)
ParseDone remaining -> return ()
ParseFailed err -> error err
main = runConduit $ CB.sourceHandle stdin .| jsonParse .| CC.map (encode . snd) .| CB.sinkHandle stdout
/tmp/some1/app/Main.hs:25:13: error:
• Couldn't match type ‘Data.ByteString.Internal.ByteString’
with ‘ByteString’
NB: ‘ByteString’ is defined in ‘Data.ByteString.Lazy.Internal’
‘Data.ByteString.Internal.ByteString’
is defined in ‘Data.ByteString.Internal’
Expected type: Conduit ByteString IO (T.Text, Value)
Actual type: ConduitM
Data.ByteString.Internal.ByteString (T.Text, Value) IO ()
• In the expression: awaitForever $ \ i -> doParse (cont i)
In a case alternative:
ParseNeedData cont -> awaitForever $ \ i -> doParse (cont i)
In the expression:
case out of
ParseYield value newOutput
-> do yield value
doParse newOutput
ParseNeedData cont -> awaitForever $ \ i -> doParse (cont i)
ParseDone remaining -> return ()
ParseFailed err -> error err
|
25 | awaitForever $ \i -> doParse (cont i)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/tmp/some1/app/Main.hs:25:34: error:
• Couldn't match type ‘ByteString’
with ‘Data.ByteString.Internal.ByteString’
NB: ‘Data.ByteString.Internal.ByteString’
is defined in ‘Data.ByteString.Internal’
‘ByteString’ is defined in ‘Data.ByteString.Lazy.Internal’
Expected type: ConduitM
Data.ByteString.Internal.ByteString (T.Text, Value) IO ()
Actual type: Conduit ByteString IO (T.Text, Value)
• In the expression: doParse (cont i)
In the second argument of ‘($)’, namely ‘\ i -> doParse (cont i)’
In the expression: awaitForever $ \ i -> doParse (cont i)
|
25 | awaitForever $ \i -> doParse (cont i)
| ^^^^^^^^^^^^^^^^
/tmp/some1/app/Main.hs:29:46: error:
• Couldn't match type ‘ByteString’
with ‘Data.ByteString.Internal.ByteString’
NB: ‘Data.ByteString.Internal.ByteString’
is defined in ‘Data.ByteString.Internal’
‘ByteString’ is defined in ‘Data.ByteString.Lazy.Internal’
Expected type: ConduitM
Data.ByteString.Internal.ByteString Data.Void.Void IO ()
Actual type: ConduitM ByteString Data.Void.Void IO ()
• In the second argument of ‘(.|)’, namely
‘jsonParse .| CC.map (encode . snd) .| CB.sinkHandle stdout’
In the second argument of ‘($)’, namely
‘CB.sourceHandle stdin
.| jsonParse .| CC.map (encode . snd) .| CB.sinkHandle stdout’
In the expression:
runConduit
$ CB.sourceHandle stdin
.| jsonParse .| CC.map (encode . snd) .| CB.sinkHandle stdout
|
29 | main = runConduit $ CB.sourceHandle stdin .| jsonParse .| CC.map (encode . snd) .| CB.sinkHandle stdout
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/tmp/some1/app/Main.hs:29:84: error:
• Couldn't match type ‘Data.ByteString.Internal.ByteString’
with ‘ByteString’
NB: ‘ByteString’ is defined in ‘Data.ByteString.Lazy.Internal’
‘Data.ByteString.Internal.ByteString’
is defined in ‘Data.ByteString.Internal’
Expected type: ConduitM ByteString Data.Void.Void IO ()
Actual type: ConduitM
Data.ByteString.Internal.ByteString Data.Void.Void IO ()
• In the second argument of ‘(.|)’, namely ‘CB.sinkHandle stdout’
In the second argument of ‘(.|)’, namely
‘CC.map (encode . snd) .| CB.sinkHandle stdout’
In the second argument of ‘(.|)’, namely
‘jsonParse .| CC.map (encode . snd) .| CB.sinkHandle stdout’
|
29 | main = runConduit $ CB.sourceHandle stdin .| jsonParse .| CC.map (encode . snd) .| CB.sinkHandle stdout
| ^^^^^^^^^^^^^^^^^^^^
答案 0 :(得分:1)
bytestring
定义了严格类型(Data.ByteString
)&懒惰类型(在模块Data.ByteString.Lazy
中)。修复代码可能就像导入Data.ByteString.Char8
而不是惰性代码一样简单。如果库使用混合物,您可以使用toStrict和fromStrict