我又一次被困在了哈斯克尔身上。这次我应该使用我正在努力理解的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种语言。任何与该问题相关的一般信息也非常受欢迎。
EDIT;后续行动:
感谢很好的答案,我提高了理解并实施了以下代码:
dropEmpty :: [[String]] -> [[String]]
dropEmpty = filter(not . null)
但是,我仍然在列表中看到空列表。这是因为我正在检查整个列表列表是否为空?如何分析我想查看“内部”列表?
答案 0 :(得分:1)
do关键字只是monads的糖语法
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定义中所看到的,>>=
的第二个参数是monad的内部类型,在您的情况下,它是[[String]]
因此,您的代码没有任何问题,您可以使用dropEmpty而无需担心IO
答案 1 :(得分:1)
getRawData :: String -> IO [[String]]
getRawData fn = do
d <- getRawData' fn
return (dropEmpty d)
getRawData
和return
是此执行块中的monadic操作。所有其他表达式都没有 IO 类型。
特别是<-
左侧的表达式,即 d ,只有普通类型[[String]]
。所有参数,即fn :: String
和(dropEmpty d) :: [[String]]
,也不在 IO 中。
因此,您可以轻松地从monadic动作(例如d
)中获取非monadic值(例如getRawData'
)。但是,您只能暂时执行此操作:您无法使d
转义执行块,仅IO d
。这是monad的“核心特征”。
这只是一个非常肤浅的解释,可以让您快速了解monadic代码。我建议你阅读monad。了解monad是如何被贬低的。以state
monad为例,通过尝试重新实现它来了解它解决了什么问题。