所以我正在为 CSV 文件编写一个实用函数的小玩具箱,并在整个测试过程中我一直在手动绑定文件
table' <- parseCSVFromFile filepath
但是(从Text.CSV
)
parseCSVFromFile :: FilePath -> IO (Either parsec-3.1.9:Text.Parsec.Error.ParseError CSV)
所以我不得不写一个快速的行来去掉这个错误 csv 废话
stripBare csv = head $ rights $ flip (:) [] csv
并将其重新定义为table = stripBare table'
. 在此之后,列表函数对 csv 文件内容起作用,并且生活继续
(题外话:令人惊讶的是没有直接的Either a b -> b
功能Data.Either
。所以我使用了Data.Either.rights :: [Either a b] -> [b]
)
我想一次性完成 csv 类型的脱衣并将其绑定到手柄上的工作。就像是
table = stripBare $ table' <- parseCSVFromFile filepath
但这会在 ( <-
) 上给出一个解析错误,说我可能缺少一个do
... 然后
table = stripBare $ do table' <- parseCSVFromFile filepath
对我大喊大叫,说do
块中的最后一个语句必须是表达式。
我究竟做错了什么?
作为一个单独的好奇心,我在这里看到
以非常简单的方式在 Haskell deugars 中做符号。
do
x <- foo
e1
e2
...
变成
foo >>= \x ->
do
e1
e2
我觉得这很有吸引力并尝试了以下行,这给了我一个类型错误
*Toy> :type (parseCSVFromFile "~/.csv") >>= \x -> x
<interactive>:1:52: error:
* Couldn't match type `Either
parsec-3.1.9:Text.Parsec.Error.ParseError'
with `IO'
Expected type: IO CSV
Actual type: Either parsec-3.1.9:Text.Parsec.Error.ParseError CSV
* In the expression: x
In the second argument of `(>>=)', namely `\ x -> x'
In the expression:
(parseCSVFromFile "~/.csv") >>= \ x -> x