Haskell在IO列表上的递归函数

pro*_*nce 0 io recursion haskell

我有以下函数迭代列表 [(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
Run Code Online (Sandbox Code Playgroud)

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

我以为do = return会照顾这个.我该怎么纠正这个?

编辑:回答我使用IO的原因:

selectAll ? extractPatternStringsselectAll从数据库中读取的地方调用该函数.

dav*_*420 7

extractPatternStrings ? IO [(Map String SqlValue)] ? IO [String]
Run Code Online (Sandbox Code Playgroud)

An IO [String]是产生[String]结果的IO操作.你使用do notation确保extractPatternStrings产生一个IO [String],而不是一个[String].

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

您应该使用此类型签名:

extractPatternStrings ? [Map String SqlValue] ? IO [String] 
Run Code Online (Sandbox Code Playgroud)

除此之外,正如@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
Run Code Online (Sandbox Code Playgroud)

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

extractPatternStrings ? [Map String SqlValue] ? [String] 
extractPatternStrings = map toString
    where
        toString ?  Map String SqlValue ? String 
        toString = fromSql . fromJust . Map.lookup "word"
Run Code Online (Sandbox Code Playgroud)

更简洁:

extractPatternStrings ? [Map String SqlValue] ? [String] 
extractPatternStrings = map (fromSql . fromJust . Map.lookup "word")
Run Code Online (Sandbox Code Playgroud)

如果你真的必须拥有原始签名,那么请使用liftM,或者通过更改你的调用代码selectAll ? liftM extractPatternStrings(我必须承认我不认识你在那里使用的运算符),或者通过定义extractPatternStrings

extractPatternStrings ? IO [Map String SqlValue] ? IO [String] 
extractPatternStrings = liftM $ map (fromSql . fromJust . Map.lookup "word")
Run Code Online (Sandbox Code Playgroud)

但我推荐前者.