Как сплющить IO [[String]]?

Я новичок в Haskell и испытываю некоторые трудности с тем, чтобы разобраться в некоторых его концепциях.

Играя с IO, я хотел сплющить IO [[String]].

Пример того, что я пробовал:

module DatabaseTestSO where

import Database.HDBC
import Database.HDBC.MySQL
import Data.Foldable

convSqlValue :: [SqlValue] -> [String]
convSqlValue xs = [ getString x | x <- xs ]
    where getString value = case fromSql value of
                Just x -> x
                Nothing -> "Null"

listValues :: [[SqlValue]] -> [[String]]
listValues [] = []
listValues xs = [ convSqlValue x | x <- xs ]

flatten :: [[a]] -> [a]
flatten = Data.Foldable.foldl (++) []

domains :: IO [[String]]
domains =
    do  conn <- connectMySQL defaultMySQLConnectInfo {
                mysqlHost       = "hostname",
                mysqlDatabase   = "dbname",
                mysqlUser       = "username",
                mysqlPassword   = "pass" }

        queryDomains <- quickQuery conn "SELECT name FROM domains" []

        return (listValues queryDomains)

Это работает с [[String]] в GHCi, как и ожидалось:

*DatabaseTestSO> flatten [["blah","blab","wah"],["bloh","blob","woh"],["blih","blib","wuh"]]
["blah","blab","wah","bloh","blob","woh","blih","blib","wuh"]

но не работает с IO [[String]], где я получаю

*DatabaseTestSO> flatten domains 

<interactive>:1:9:
    Couldn't match expected type `[[a0]]'
                with actual type `IO [[String]]'
    In the first argument of `flatten', namely `domains'
    In the expression: flatten domains
    In an equation for `it': it = flatten domains

Я полагаю, что я не могу использовать функцию, которая должна быть чистой с типами IO? Могу ли я преобразовать IO [[String]] в [[String]]? Как правильно решить эту проблему?

5
задан matthias krull 24 December 2011 в 19:12
поделиться