繁体   English   中英

IO列表上的Haskell递归函数

[英]Haskell Recursive function over IO list

我具有以下在列表[(Map String SqlValue)]迭代的功能。

extractPatternStrings ∷ IO [(Map String SqlValue)] → IO [String] 
extractPatternStrings [] = do
    return []
extractPatternStrings lst = do
    (m:ms) ←  lst
    return $ (toString m) : (extractPatternStrings ms)
    where
        toString ∷  Map String SqlValue → String 
        toString m = (fromSql . fromJust . (Map.lookup "word"))∷ String

执行空列表的情况是告诉我它与实际的[t0]无法匹配预期的IO [Map String SqlValue] [t0]

我认为do = return会解决这个问题。 我该如何纠正?

编辑:要回答为什么我使用IO:

selectAll ↠ extractPatternStrings中调用该函数,其中selectAll从数据库中读取。

extractPatternStrings ∷ IO [(Map String SqlValue)] → IO [String]

IO [String]是产生[String]结果的IO操作。 使用do表示法可确保extractPatternStrings产生IO [String]而不是[String]

IO [(Map String SqlValue)]是产生[Map String SqlValue]结果的IO操作。 但是您不能针对IO操作进行模式匹配。 您使用的语法是直接与列表匹配,而不是与产生列表的IO操作匹配。

您应该改用以下类型签名:

extractPatternStrings ∷ [Map String SqlValue] → IO [String] 

除此之外,正如@missingno所指出的,这不必是IO操作:

extractPatternStrings ∷ [Map String SqlValue] → [String] 
extractPatternStrings []     = []
extractPatternStrings (m:ms) = toString m : extractPatternStrings ms
    where
        toString ∷  Map String SqlValue → String 
        toString m = (fromSql . fromJust . (Map.lookup "word"))∷ String

或者,更好(并修复toString的错误):

extractPatternStrings ∷ [Map String SqlValue] → [String] 
extractPatternStrings = map toString
    where
        toString ∷  Map String SqlValue → String 
        toString = fromSql . fromJust . Map.lookup "word"

更简洁地说:

extractPatternStrings ∷ [Map String SqlValue] → [String] 
extractPatternStrings = map (fromSql . fromJust . Map.lookup "word")

如果您确实必须具有原始签名,则可以使用liftM ,方法是将调用代码更改为selectAll ↠ liftM extractPatternStrings (并且我必须承认我不认识您在此使用的运算符),或者通过将extractPatternStrings定义为

extractPatternStrings ∷ IO [Map String SqlValue] → IO [String] 
extractPatternStrings = liftM $ map (fromSql . fromJust . Map.lookup "word")

但我推荐前者。

return将您的返回值包装在IO ,以便处理返回类型IO [String] 但是,它对您的参数类型没有帮助,它是[(Map String SqlValue)] ,但是您正在尝试对空列表进行模式匹配。 基本上,您无法根据IO值进行模式匹配。

因此,您应该摆脱IO(在代码中似乎完全没有必要),或者如果您确实希望函数接受IO(尽管我无法想象为什么),则必须先取消包装参数您可以对其进行模式匹配,如下所示:

extractPatternStrings lstIO = do
  lst <- lstIO
  case lst of
    [] -> ...
    (m:ms) -> ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM