Haskell错误将CSV文件绑定到句柄

时间:2017-01-19 07:28:47

标签: csv haskell functional-programming io-monad do-notation

所以我正在为CSV文件编写一个实用函数的小玩具箱,并在整个过程中测试我手动绑定文件的函数

table' <- parseCSVFromFile filepath

但是(来自Text.CSV

parseCSVFromFile :: FilePath -> IO (Either parsec-3.1.9:Text.Parsec.Error.ParseError CSV)

所以我不得不写一条快速线来消除这个错误csv crap

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块中的最后一个语句必须是表达式。

我做错了什么?

作为一个单独的好奇心,我看到了here那个

以一种非常简单的方式在Haskell desugars中表示。

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

1 个答案:

答案 0 :(得分:0)

代码如

head $ rights $ flip (:) [] csv

很危险。您利用head的偏好来隐藏csv可能是Left something的事实。我们可以将其重写为

= head $ rights $ (:) csv []
= head $ rights [csv]
= case csv of
     Left _  -> error "Left found!"
     Right x -> x

通常最好直接在Left IO块中处理do情况。类似于:(伪代码跟随)

foo :: String -> IO ()
foo filepath = do
   table' <- parseCSVFromFile filepath
   case table' of
      Left err -> do
         putStrLn "Error in parsing CSV"
         print err
         moreErrorHandlingHere
      Right table -> do
         putStrLn "CSV loaded!"
         use table