简体   繁体   English

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

[英]How can I avoid an error involving lazy bytestrings?

I tried the following code : 我尝试了以下代码:

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 accepts to give me a type but somehow cannot compute "it" : ghci 7.10.3接受给我一个类型,但是以某种方式无法计算“它”:

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

ghc 7.10.3 links but gives : ghc 7.10.3链接,但给出了:

collect2: error: ld returned 1 exit status

What is wrong with this expression ? 这个表达式有什么问题? I know it is an ugly expression and that it may look better with OverloadedStrings, but still, I am perplexed. 我知道这是一个丑陋的表达式,使用OverloadedStrings可能看起来更好,但仍然感到困惑。

The thing that puzzled me was what type you were read ing the string "stuff" to, so I looked at the types . 让我感到困惑的是,您正在read什么类型的字符串“ stuff”,所以我查看了这些类型

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

where Query is an alias for [(ByteString, Maybe ByteString)] . Query是[(ByteString, Maybe ByteString)]的别名 So in this context you are specializing read to: 因此,在这种情况下,您专门read

read :: String -> ByteString

Looking at the relevant Read instance , we see: 查看相关的Read实例 ,我们看到:

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

and

packChars :: [Char] -> ByteString

So, ByteString just delegates to String for reading, and then packs the result. 因此,ByteString仅委托给String进行读取,然后打包结果。 So your code eventually boils down to: 因此,您的代码最终可以归结为:

read "stuff" :: String

which fails, of course. 当然会失败。 There's no String that Shows itself as the five characters stuff . 有没有字符串,显示自己作为五个字符stuff

Rather, it looks to me like you just want to be using T.pack to convert this to a ByteString, just as you do for your other strings. 相反,在我看来,您就像要使用T.pack将其转换为ByteString一样,就像处理其他字符串一样。

Your expression is 'correct' in a strict sense, that is to say it is well-typed, but your problem is what you're computing here: 从严格意义上来说,您的表达是“正确的”,也就是说,它的类型正确,但是您的问题是您在此处计算的内容:

read "stuff"

This is actually communicated in the error message: 这实际上是在错误消息中传达的:

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

(Note that this is not an error – it is an exception, which arises when running the program, not when compiling it.) (请注意,这不是错误,它是一个例外,在运行程序而不是编译程序时会发生。)

I don't know what you were trying to construct when you wrote read "stuff" , but there's nothing that "stuff" can be interpreted as, so it fails to parse. 我不知道您在写read "stuff"时试图构造什么read "stuff" ,但是"stuff"没有什么可以解释的,因此无法解析。

Examples of valid uses of read are: read "0" :: Int , read "True" :: Bool and so on. 有效使用read示例包括: read "0" :: Intread "True" :: Bool等。 read "stuff" is meaningless and will naturally cause an exception. read "stuff"是没有意义的,自然会引起异常。

Perhaps you meant maybeRead :: Read a => String -> Maybe a from Data.(Lazy.)Text.Read ? 也许你的意思是,也许maybeRead :: Read a => String -> Maybe a来自Data.(Lazy.)Text.Read吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM