我尝试了以下代码:
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可能看起来更好,但是仍然感到困惑。
答案 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" :: Int
,read "True" :: Bool
,依此类推。 read "stuff"
毫无意义,自然会导致异常。
也许您是说maybeRead :: Read a => String -> Maybe a
中的Data.(Lazy.)Text.Read
吗?