【问题标题】:Haskell I/O: Filtering empty lists in CSV data-setHaskell I/O:过滤 CSV 数据集中的空列表
【发布时间】:2016-04-16 16:57:14
【问题描述】:

我又一次被 haskell 困住了。这次我应该使用我难以理解的 IO 过滤 CSV 数据集。任何额外的相关信息表示赞赏。

结构是预先确定的,对我来说似乎很混乱。这真的是一个人应该做的吗? (我仍然必须这样做,所以这是一个有点“侧面”的问题)。

getRawData' :: String -> IO [[String]]
getRawData' fn = do
    s <- readFile fn 
    return $ parseCSVsimple s 



getRawData :: String -> IO [[String]]
getRawData fn = do
    d <- getRawData' fn
    return (dropEmpty d)



dropEmpty [[String]] -> [[String]] 

DropEmpty - 这是我需要帮助的地方 对于“正常”列表,我会直接过滤它,但是这个 IO 和不同的函数相互调用让我感到困惑。

对不起,愚蠢的问题,我已经编程了 8 个月,从那时起不得不使用 6-7 种语言。任何与该问题相关的一般信息也非常感谢。

编辑;跟进:

感谢良好的答案,我提高了理解并实现了以下代码:

dropEmpty :: [[String]] -> [[String]]
dropEmpty = filter(not . null) 

但是,我仍然在列表中看到空列表。这是因为我正在检查整个列表列表是否为空?如何确定我想检查“内部”列表?

【问题讨论】:

  • 一旦你到达dropEmpty,你就在 IO 之外,只需要关心纯粹的 Haskell。所以,只需像普通列表一样过滤它。
  • 你的 dropEmpty 函数是正确的。请记住,Haskell 的列表是不可变的,因此您的 dropEmpty 输入列表不会被修改,您必须检查函数的结果

标签: list haskell filter io


【解决方案1】:

do 关键字只是 monad 的一种糖语法

Monad 是这样定义的:

class Monad m where
  (>>=) :: m a -> (a -> m b) -> m b
  return :: a -> m a

你的getRawData函数相当于

getRawData fn = getRawData' fn >>= \d -> return (dropEmpty d)

正如您在 monad 定义中看到的,&gt;&gt;= 的第二个参数是 monad 的内部类型,在您的情况下,它是 [[String]]

所以你的代码没有问题,你可以使用你的dropEmpty而不用担心IO

【讨论】:

  • 谢谢!我现在就能弄明白了
【解决方案2】:
getRawData :: String -> IO [[String]]
getRawData fn = do
  d <- getRawData' fn
  return (dropEmpty d)

getRawDatareturn 是这个 do 块中的一元动作。所有其他表达式都没有 IO 类型。

特别是&lt;- 左边的表达式,即d,只有普通类型[[String]]。所有参数,即fn :: String(dropEmpty d) :: [[String]],也不在IO中。

因此,您可以轻松地从单子操作(例如 getRawData')中获取非单子值(例如 d)。但是,您只能暂时这样做:您不能让 d 逃脱 do 块,只能让 IO d 逃脱。这是一般单子的“核心特征”。

这只是一个非常肤浅的解释,让您快速入门一元代码。我建议你阅读 monads。了解如何对 monad 进行脱糖。以state monad 为例,通过尝试重新实现它来了解它解决了什么问题。

【讨论】:

  • 非常感谢 :) 我想我能理解这一点!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-04
  • 2014-11-27
  • 1970-01-01
  • 1970-01-01
  • 2020-11-07
  • 1970-01-01
相关资源
最近更新 更多