理解 Haskell (<-) 语法糖
Understanding Haskell (<-) syntactic sugar
我正在尝试使用 Cassava 解析 CSV 文件。我想要一个函数,如果解析不成功,returns Nothing
,否则 Just (V.Vector (String, String, String))
。
我正在使用以下代码:
{-# LANGUAGE ScopedTypeVariables #-}
module Lib
( someFunc
) where
import qualified Data.ByteString.Lazy as BL
import Data.Csv
import qualified Data.Vector as V
type Dataset = (String, String, String)
someFunc :: Maybe (V.Vector Dataset)
someFunc = do
csvData <- BL.readFile "TAEE3.SA.csv"
case decode HasHeader csvData :: Either String (V.Vector (String, String, String)) of
Left a -> Nothing
Right v -> Just v
错误是:
• Couldn't match type ‘IO’ with ‘Maybe’
Expected type: Maybe BL.ByteString
Actual type: IO BL.ByteString
• In a stmt of a 'do' block: csvData <- BL.readFile "TAEE3.SA.csv"
In the expression:
do csvData <- BL.readFile "TAEE3.SA.csv"
case decode HasHeader csvData ::
Either String (V.Vector (String, String, String))
of
Left a -> Nothing
Right v -> Just v
In an equation for ‘someFunc’:
someFunc
= do csvData <- BL.readFile "TAEE3.SA.csv"
case decode HasHeader csvData ::
Either String (V.Vector (String, String, String))
of
Left a -> Nothing
Right v -> Just v
|
14 | csvData <- BL.readFile "TAEE3.SA.csv"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
好像<-
功能完全没有用。难道不应该 return 一个 a
in IO a
monad 吗?
虽然 <-
确实在 IO a
中为您提供了 a
,但它并不是通过将其从 IO monad 中取出来实现的。一般来说,不可能从 monad 中取出一个值。它实际上所做的是将 do
块的其余部分也放入 monad 中。为了解决这个问题,您需要使函数 return 的结果在 IO
中,然后添加一个 return
以将最终的 Maybe
包装回 IO
:
{-# LANGUAGE ScopedTypeVariables #-}
module Lib
( someFunc
) where
import qualified Data.ByteString.Lazy as BL
import Data.Csv
import qualified Data.Vector as V
type Dataset = (String, String, String)
someFunc :: IO (Maybe (V.Vector Dataset))
someFunc = do
csvData <- BL.readFile "TAEE3.SA.csv"
return $ case decode HasHeader csvData :: Either String (V.Vector (String, String, String)) of
Left a -> Nothing
Right v -> Just v
我正在尝试使用 Cassava 解析 CSV 文件。我想要一个函数,如果解析不成功,returns Nothing
,否则 Just (V.Vector (String, String, String))
。
我正在使用以下代码:
{-# LANGUAGE ScopedTypeVariables #-}
module Lib
( someFunc
) where
import qualified Data.ByteString.Lazy as BL
import Data.Csv
import qualified Data.Vector as V
type Dataset = (String, String, String)
someFunc :: Maybe (V.Vector Dataset)
someFunc = do
csvData <- BL.readFile "TAEE3.SA.csv"
case decode HasHeader csvData :: Either String (V.Vector (String, String, String)) of
Left a -> Nothing
Right v -> Just v
错误是:
• Couldn't match type ‘IO’ with ‘Maybe’
Expected type: Maybe BL.ByteString
Actual type: IO BL.ByteString
• In a stmt of a 'do' block: csvData <- BL.readFile "TAEE3.SA.csv"
In the expression:
do csvData <- BL.readFile "TAEE3.SA.csv"
case decode HasHeader csvData ::
Either String (V.Vector (String, String, String))
of
Left a -> Nothing
Right v -> Just v
In an equation for ‘someFunc’:
someFunc
= do csvData <- BL.readFile "TAEE3.SA.csv"
case decode HasHeader csvData ::
Either String (V.Vector (String, String, String))
of
Left a -> Nothing
Right v -> Just v
|
14 | csvData <- BL.readFile "TAEE3.SA.csv"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
好像<-
功能完全没有用。难道不应该 return 一个 a
in IO a
monad 吗?
虽然 <-
确实在 IO a
中为您提供了 a
,但它并不是通过将其从 IO monad 中取出来实现的。一般来说,不可能从 monad 中取出一个值。它实际上所做的是将 do
块的其余部分也放入 monad 中。为了解决这个问题,您需要使函数 return 的结果在 IO
中,然后添加一个 return
以将最终的 Maybe
包装回 IO
:
{-# LANGUAGE ScopedTypeVariables #-}
module Lib
( someFunc
) where
import qualified Data.ByteString.Lazy as BL
import Data.Csv
import qualified Data.Vector as V
type Dataset = (String, String, String)
someFunc :: IO (Maybe (V.Vector Dataset))
someFunc = do
csvData <- BL.readFile "TAEE3.SA.csv"
return $ case decode HasHeader csvData :: Either String (V.Vector (String, String, String)) of
Left a -> Nothing
Right v -> Just v