我是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
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
答案 0 :(得分:2)
案例的右侧:
Right v -> ...
不仅需要将IO操作v
转换为所需的类型[[Float]]
的IO操作,而且还可以在某些IO中使用结果(同样,您第一次成功的尝试尝试将其打印出来。
将v
转换为[[Float]]
实际上很容易。您不需要V.concatMap
或makeFloatList
。相反,使用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]]
>