How to smooth IO [[String]]?

I am new to Haskell and have some difficulty wrapping some of his concepts around.

While playing with IO, I wanted to flatten IO [[String]].

An example of what I tried:

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)

This works with [[String]]in GHCi, as expected:

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

but not with IO [[String]]where I get

*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

I think I cannot use a function that should be clean with I / O types? Is it possible to convert IO [[String]]to [[String]]? How to solve this problem?

+5
source share
2 answers

, IO something. something, , something ( something [[String]]). , , , , .

.

  • . :

    do
      ds <- domains       -- Perform action, and save result in ds
      return $ flatten ds -- Flatten the result ds
    
  • , - , . . liftM Control.Monad.

    import Control.Monad
    -- ...
    
    do
      -- Creates a new action that flattens the result of domains
      let getFlattenedDomains = liftM flatten domains
    
      -- Perform the new action to get ds, which contains the flattened result
      ds <- getFlattenedDomains
    
      return ds
    

PS. , domains getDomains, , . ; , .

+15

- "" -, flatten, . : fmap - , map , fmap Functor, IO.

flattenIO xs = fmap flatten xs

do, IO. :

flattenIO xs = do ys <- xs
                  return (flatten ys)

... fmap .

+10

All Articles