I have the following function that iterates over a 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
Execpt the empty list case is telling me that it couldn’t match the expected IO [Map String SqlValue] with actual [t0].
I thought the do = return would have taken care of this. How should I correct this?
Edit: To answer why I am using IO:
The function is being called from selectAll ↠ extractPatternStrings where selectAll reads from a database.
An
IO [String]is an IO action that produces a[String]result. Your use of do notation ensuresextractPatternStringsproduces anIO [String], not a[String].An
IO [(Map String SqlValue)]is an IO action that produces a[Map String SqlValue]result. But you cannot pattern match against an IO action. The syntax you use is for matching directly against a list, not against an IO action that produces a list.You should use this type signature instead:
Except that, as @missingno points out, this doesn’t need to be an IO action:
Or, better (and fixing an error in
toString):More succinctly:
If you really must have the original signature, then use
liftM, either by changing your calling code toselectAll ↠ liftM extractPatternStrings(and I must confess I don’t recognise the operator you use there), or by definingextractPatternStringsasBut I recommend the former.