如何避免涉及惰性字节串的错误?

时间:2018-11-12 18:27:59

标签: haskell

我尝试了以下代码:

import Network.HTTP.Types
import Data.Text as T
import Data.ByteString.Builder

it = toLazyByteString $ encodePath (Prelude.map T.pack ["foo","bar"]) [(read "stuff",Nothing)]

main = print it

ghci 7.10.3接受给我一个类型,但是以某种方式无法计算“它”:

"*** Exception: Prelude.read: no parse

ghc 7.10.3链接,但给出了:

collect2: error: ld returned 1 exit status

此表达式有什么问题?我知道这是一个丑陋的表达式,使用OverloadedStrings可能看起来更好,但是仍然感到困惑。

2 个答案:

答案 0 :(得分:2)

让我感到困惑的是,您read将字符串“ stuff”键入到什么类型,所以我looked at the types

encodePath :: [Text] -> Query -> Builder

其中Query is an alias for [(ByteString, Maybe ByteString)]。因此,在这种情况下,您将read专用于:

read :: String -> ByteString

the relevant Read instance看,我们看到:

instance Read ByteString where
    readsPrec p str = [ (packChars x, y) | (x, y) <- readsPrec p str ]

packChars :: [Char] -> ByteString

因此,ByteString只是委托给String进行读取,然后打包结果。因此,您的代码最终可以归结为:

read "stuff" :: String

当然会失败。没有字符串显示为五个字符stuff

相反,在我看来,您就像要使用T.pack一样,将其转换为ByteString,就像处理其他字符串一样。

答案 1 :(得分:1)

从严格意义上讲,您的表达式是“正确的”,也就是说,它的类型正确,但是您的问题是您在此处计算的内容:

read "stuff"

这实际上是在错误消息中传达的:

"*** Exception: Prelude.read: no parse"
--              ^^^^^^^^^^^^
-- The underlined means the exception is due to the `read` function.

(请注意,这不是错误,它是一个例外,它是在运行程序时而不是在编译程序时发生的。)

我不知道您在编写read "stuff"时试图构造什么,但是"stuff"并没有什么可以解释的,因此无法解析。

read的有效用法示例包括:read "0" :: Intread "True" :: Bool,依此类推。 read "stuff"毫无意义,自然会导致异常。

也许您是说maybeRead :: Read a => String -> Maybe a中的Data.(Lazy.)Text.Read吗?