缺少结果类型?在函数 length :: Monad m => ByteString m r -> m (Of Int r)
Missing type of result? In function length :: Monad m => ByteString m r -> m (Of Int r)
我有一个简单的函数,可以一次读取一个字节的二进制文件。它会出现编译时错误,如下所示。问题似乎是 bs2
,BSSC.length
的结果 ByteString,具有未知类型。我是否缺少 r
上的类型约束?
import qualified Data.ByteString.Streaming.Char8 as BSSC
main :: IO ()
main = runResourceT $ dump $ BSSC.readFile "filename"
dump :: (MonadIO m) => BSSC.ByteString m r -> m ()
dump bs = do
len :> bs2 <- BSSC.length bs -- Data.Functor.Of (:>)
if len <= 1 then return ()
else dump $ BSSC.putStr $ BSSC.splitAt 1 bs2
编译时错误:
Main.hs:166:46: error:
• Couldn't match expected type ‘BSSC.ByteString
(BSSC.ByteString m) r0’
with actual type ‘r’
‘r’ is a rigid type variable bound by
the type signature for:
dump :: forall (m :: * -> *) r.
MonadIO m =>
BSSC.ByteString m r -> m ()
at Main.hs:162:9
• In the second argument of ‘BSSC.splitAt’, namely ‘bs2’
In the second argument of ‘($)’, namely ‘BSSC.splitAt 1 bs2’
In the second argument of ‘($)’, namely
‘BSSC.putStr $ BSSC.splitAt 1 bs2’
• Relevant bindings include
bs2 :: r (bound at Main.hs:164:12)
bs :: BSSC.ByteString m r (bound at Main.hs:163:6)
dump :: BSSC.ByteString m r -> m () (bound at Main.hs:163:1)
您可以使用 bs
作为 splitAt
的第二个参数来修补类型不匹配
import qualified Data.ByteString.Streaming.Char8 as BSSC
main :: IO ()
main = runResourceT $ dump $ BSSC.readFile "filename"
dump :: (MonadIO m) => BSSC.ByteString m r -> m ()
dump bs = do
len :> bs2 <- BSSC.length bs
if len <= 1 then return ()
else dump $ BSSC.putStr $ BSSC.splitAt 1 bs
但它不会像您预期的那样工作。我想它将读取文件的次数与其中的字母一样多。
如果你想要递归,你应该使用
import qualified Data.ByteString.Streaming.Char8 as BSSC
main :: IO ()
main = runResourceT $ dump $ BSSC.readFile "filename"
dump :: (MonadIO m) => BSSC.ByteString m r -> m ()
dump bs = do
split <- BSSC.uncons bs
case split of
Left _ -> return ()
Right (x, xs) -> putStr (show x) >> dump xs
我没有带编译器,所以我的代码片段中可能存在编译问题。
streaming-bytestring 中的 ByteString
类型有两个类型参数。第一个是产生值的基础 monad m
(通常是 IO
)。
第二个是一个特殊的结束值r
,一旦ByteString
用完就会返回。通常它将是一个无信息的 ()
。但是,它对于定义像 splitAt :: Monad m => Int64 -> ByteString m r -> ByteString m (ByteString m r)
这样的函数非常有用。该类型表示:"give me a limit position and a effectful stream of bytes that returns with an r
, I will give you another stream that is no longer than the limit and returns with a effectful stream of bytes that returns with an r
." 嵌套在外部流中的结束流只有在外部流耗尽后才能到达。
length
的类型为 Monad m => ByteString m r -> m (Of Int r)
。它使用作为参数接收的值流和 returns 基本 monad 中的一个动作。 ByteString
不存在了。您传递给 splitAt
的 bs2
不是 ByteString
,而是原始 ByteString
的结束值,其类型为 r
。这会导致类型错误。
我有一个简单的函数,可以一次读取一个字节的二进制文件。它会出现编译时错误,如下所示。问题似乎是 bs2
,BSSC.length
的结果 ByteString,具有未知类型。我是否缺少 r
上的类型约束?
import qualified Data.ByteString.Streaming.Char8 as BSSC
main :: IO ()
main = runResourceT $ dump $ BSSC.readFile "filename"
dump :: (MonadIO m) => BSSC.ByteString m r -> m ()
dump bs = do
len :> bs2 <- BSSC.length bs -- Data.Functor.Of (:>)
if len <= 1 then return ()
else dump $ BSSC.putStr $ BSSC.splitAt 1 bs2
编译时错误:
Main.hs:166:46: error:
• Couldn't match expected type ‘BSSC.ByteString
(BSSC.ByteString m) r0’
with actual type ‘r’
‘r’ is a rigid type variable bound by
the type signature for:
dump :: forall (m :: * -> *) r.
MonadIO m =>
BSSC.ByteString m r -> m ()
at Main.hs:162:9
• In the second argument of ‘BSSC.splitAt’, namely ‘bs2’
In the second argument of ‘($)’, namely ‘BSSC.splitAt 1 bs2’
In the second argument of ‘($)’, namely
‘BSSC.putStr $ BSSC.splitAt 1 bs2’
• Relevant bindings include
bs2 :: r (bound at Main.hs:164:12)
bs :: BSSC.ByteString m r (bound at Main.hs:163:6)
dump :: BSSC.ByteString m r -> m () (bound at Main.hs:163:1)
您可以使用 bs
作为 splitAt
import qualified Data.ByteString.Streaming.Char8 as BSSC
main :: IO ()
main = runResourceT $ dump $ BSSC.readFile "filename"
dump :: (MonadIO m) => BSSC.ByteString m r -> m ()
dump bs = do
len :> bs2 <- BSSC.length bs
if len <= 1 then return ()
else dump $ BSSC.putStr $ BSSC.splitAt 1 bs
但它不会像您预期的那样工作。我想它将读取文件的次数与其中的字母一样多。
如果你想要递归,你应该使用
import qualified Data.ByteString.Streaming.Char8 as BSSC
main :: IO ()
main = runResourceT $ dump $ BSSC.readFile "filename"
dump :: (MonadIO m) => BSSC.ByteString m r -> m ()
dump bs = do
split <- BSSC.uncons bs
case split of
Left _ -> return ()
Right (x, xs) -> putStr (show x) >> dump xs
我没有带编译器,所以我的代码片段中可能存在编译问题。
streaming-bytestring 中的 ByteString
类型有两个类型参数。第一个是产生值的基础 monad m
(通常是 IO
)。
第二个是一个特殊的结束值r
,一旦ByteString
用完就会返回。通常它将是一个无信息的 ()
。但是,它对于定义像 splitAt :: Monad m => Int64 -> ByteString m r -> ByteString m (ByteString m r)
这样的函数非常有用。该类型表示:"give me a limit position and a effectful stream of bytes that returns with an r
, I will give you another stream that is no longer than the limit and returns with a effectful stream of bytes that returns with an r
." 嵌套在外部流中的结束流只有在外部流耗尽后才能到达。
length
的类型为 Monad m => ByteString m r -> m (Of Int r)
。它使用作为参数接收的值流和 returns 基本 monad 中的一个动作。 ByteString
不存在了。您传递给 splitAt
的 bs2
不是 ByteString
,而是原始 ByteString
的结束值,其类型为 r
。这会导致类型错误。