【问题标题】:Understanding Haskell (<-) syntactic sugar理解 Haskell (<-) 语法糖
【发布时间】:2020-07-24 17:11:01
【问题描述】:

我正在尝试使用 Cassava 解析 CSV 文件。我想要一个函数,如果解析不成功则返回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"
   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^

就像&lt;- 函数根本不起作用。它不应该在IO a monad 中返回a 吗?

【问题讨论】:

  • 这行不通,因为您试图在 Maybe monad 中执行 IO (readFile)。 &lt;- 也不是函数,它只是 &gt;&gt;= 的语法糖

标签: haskell monads do-notation


【解决方案1】:

虽然&lt;- 确实在IO a 中为您提供了a,但它不会通过将其从IO monad 中取出来实现。一般来说,不可能从 monad 中获取值。它实际上所做的是将 do 块的其余部分也放入 monad。考虑到这一点,您需要让您的函数在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

【讨论】:

  • 你的意思是什么是不可能的?
  • @testin3r Maybe 是一个单子。如果我给你Nothing 并告诉你从中取出价值,那会是什么价值?
猜你喜欢
  • 2011-12-23
  • 2015-05-24
  • 1970-01-01
  • 2015-08-22
  • 1970-01-01
  • 2010-10-31
  • 2016-01-22
  • 2023-03-08
  • 1970-01-01
相关资源
最近更新 更多