我有以下函数迭代列表[(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
执行空列表案例告诉我它与预期的IO [Map String SqlValue]
与实际[t0]
无法匹配。
我认为do = return
会照顾到这一点。我该怎么纠正这个?
编辑:回答我使用IO的原因:
从selectAll ↠ extractPatternStrings
调用该函数,其中selectAll从数据库中读取。
答案 0 :(得分:7)
extractPatternStrings ∷ IO [(Map String SqlValue)] → IO [String]
IO [String]
是一个产生[String]
结果的IO操作。您使用记号确保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")
但我推荐前者。
答案 1 :(得分:2)
return
将您的返回值包装在IO
中,以便处理返回类型IO [String]
。但是它对您的参数类型([(Map String SqlValue)]
没有帮助,但是您尝试将模式匹配到空列表中。基本上你不能模式匹配IO值。
所以你应该摆脱IO(你的代码中似乎完全没有必要)或者如果你真的希望函数采用IO(虽然我无法想象为什么你会这样做),你必须解开在你可以对它进行模式匹配之前你的论点,看起来像这样:
extractPatternStrings lstIO = do
lst <- lstIO
case lst of
[] -> ...
(m:ms) -> ...