Haskell:将CSV文件解析为浮动列表列表

时间:2018-08-20 01:17:12

标签: csv haskell

我是Haskell的新手,试图读取一个csv文件并列出浮点列表,但出现“ IO”编译器错误。带有GHCI 8.0.2的Ubuntu 18.04。 CSV文件如下所示:

2,112,66,22,0,25.0,0.307,24,0
3,113,44,13,0,22.4,0.140,22,0

我的代码:

{-# LANGUAGE ScopedTypeVariables #-}
import qualified Data.ByteString.Lazy as BL
import Data.Csv
import qualified Data.Vector as V

main = do
    csvData <- BL.readFile "data/pima.csv"
    case decode NoHeader csvData of
        Left err -> putStrLn err
        --Right v -> V.forM_ v ( printMyStuff ) --this works
        Right v -> V.concatMap v makeFloatList --'IO' compile fail


printMyStuff [v1 :: Float, v2 :: Float, v3 :: Float,
           v4 :: Float, v5 :: Float, v6 :: Float,
           v7 :: Float, v8 :: Float, v9 :: Float] =
    putStrLn ( show v1 ++ ", " ++ show v2 ++ ", " ++ show v3 ++
         ", " ++ show v4 ++ ", " ++ show v5 ++ ", " ++ show v6 ++
         ", " ++ show v7 ++ ", " ++ show v8 ++ ", " ++ show v9)

makeFloatList [v1 :: Float, v2 :: Float, v3 :: Float,
           v4 :: Float, v5 :: Float, v6 :: Float,
           v7 :: Float, v8 :: Float, v9 :: Float] =
                                     [v1,v2,v3,v4,v5,v6,v7,v8,v9]

,(第一个)错误消息是:

CSVFloat.hs:11:20: error:
    • Couldn't match type ‘V.Vector’ with ‘IO’
      Expected type: IO ()
        Actual type: V.Vector ()
    • In the expression: V.concatMap v makeFloatList
      In a case alternative: Right v -> V.concatMap v makeFloatList
      In a stmt of a 'do' block:
        case decode NoHeader csvData of
          Left err -> putStrLn err
          Right v -> V.concatMap v makeFloatList
   |
11 |         Right v -> V.concatMap v makeFloatList --'IO' compile fail
   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^

1 个答案:

答案 0 :(得分:2)

案例的右侧:

Right v -> ...

不仅需要将IO操作v转换为所需的类型[[Float]]的IO操作,而且还可以在某些IO中使用结果(同样,您第一次成功的尝试尝试将其打印出来。

v转换为[[Float]]实际上很容易。您不需要V.concatMapmakeFloatList。相反,使用V.toList将其转换为行列表,如果为其赋予正确的类型签名,则decode函数将“弄清楚”您希望每一行都是浮点数列表。因此,您可以编写:

Right v -> do let mylist = V.toList v :: [[Float]]
              ...

,但是您仍然必须决定如何处理mylist。打印它是一种选择:

Right v -> do let mylist = V.toList v :: [[Float]]
              print v

给予:

> main
[[2.0,112.0,66.0,22.0,0.0,25.0,0.307,24.0,0.0],
 [3.0,113.0,44.0,13.0,0.0,22.4,0.14,22.0,0.0]]
>