Get value from "IO a" is interpreted as list - haskell

I'm learning haskell with wikibooks.
Given is the signature. The solution to the problem is:
sequenceIO :: [IO a] -> IO [a]
sequenceIO [] = return []
sequenceIO (a:as) = do {v <-a ; vs <- (sequenceIO as) ; return (v : vs)}
My solution was (which does not work):
sequenceIO xs = return (foldl get [] xs)
where get ys act = do y <- act
ys ++ [y]
The "get" singled out as a function:
gett :: [a] -> IO a -> [a]
gett ys act = do y <- act
ys ++ y
will not work: a list as a second parameter is infered. Why? In the solution the v <-a works too.

The reason your solution doesn't work is that you cannot simply escape the IO Monad. Once you are in the IO Monad, you will always be. This is actually one of the really great things about Haskell, because you can't hide side effects and can tell by a functions type signature what type of effects it is allowed to do.
The type signature of your gett function should actually be
gett :: [a] -> IO a -> IO [a]
However you're function will still not typecheck:
1) A small oversight: ys ++ y should actually be ys ++ [y] (as it was for get in the where clause) because append (++) works on lists.
2) ys ++ [y] would still have the wrong type. It must be of type IO [a] but is of type [a]. You can get it into IO [a] by doing return $ ys ++ [y]. Here return has type return :: a -> IO a, it lifts any value into the monad.
gett is then:
gett :: [a] -> IO a -> IO [a]
gett ys act = do
y <- act
return $ ys ++ [y]
We're now getting close, but we're not quite there yet. Now the problem is with foldl get [] xs: foldl works on plain lists, not on lists inside monads. However, we can use foldM from here and write sequenceIO as follows:
sequenceIO :: [IO a] -> IO [a]
sequenceIO xs = foldM gett [] xs
which should typecheck and work.
Full program:
import Control.Monad (foldM) -- this only imports foldM from Control.Monad
gett :: [a] -> IO a -> IO [a]
gett ys act = do
y <- act
return $ ys ++ [y]
sequenceIO :: [IO a] -> IO [a]
sequenceIO xs = foldM gett [] xs
Now a good exercise is to figure out how foldM works ;)

Related

Doing recursion within an IO monad

I have been trying to figure out how to do recursion within an IO monad.
I am familiar with doing recursion with pure functions, but have not been able to transfer this knowledge to IO monads.
Recursion with pure functions
I'm comfortable with doing recursion with pure functions such as the foo function below.
foo (x:y:ys) = foo' x y ++ foo ys
A function with IO [String] output
I made a function like goo below that does what I need and has an IO output.
goo :: String -> String -> IO [String]
goo xs ys = goo' xs ys
Trying to get recursion inside an IO monad
When I try to do recursion within an IO monad (e.g., a "main" function) I cannot. I've looked up liftM, replicateM, and the undo-the-IO <- operator or function. I want an IO monad like hoo or hoo' (apologies for the gibberish that follows).
hoo :: [String] -> IO [String]
hoo (xs:ys:yss) = do
let rs = goo xs ys ++ hoo yss
return rs
or
hoo' :: [String] -> IO [String]
hoo' (xs:ys:yss) = do
rs <- goo xs ys
let gs = rs ++ hoo' yss
return gs
(BTW, in case you are wondering what my project is, I'm writing a Genetic Algorithm program from scratch for a course. My goo function takes two parents and breeds two offspring, which are returned as an IO because goo uses a random number generator. What I need to do is to to use a recursive hoo function to use goo to breed 20 offspring from a list of 20 parents. The idea I have is to take the first two parents in the list, breed two offspring, take the next two parents on the list, breed another pair of offspring, so on and so forth.)
If you find do notation confusing, my recommendation would be to not use it at all. You can do everything you need with >>=. Just pretend its type is
(>>=) :: IO a -> (a -> IO b) -> IO b
That said, let's look at your code.
let in a do block gives a name to some value. That's the same thing it does outside of do, so that's not helpful here (it gives you no additional power).
<- is more interesting: It acts as an "extract a value from IO locally" construct (if you squint a bit).
hoo :: [String] -> IO [String]
hoo (xs:ys:yss) = do
-- The right-hand side (goo xs ys) has type IO [String], ...
rs <- goo xs ys
-- ... so rs :: [String].
-- We can apply the same construct to our recursive call:
hs <- hoo yss
-- hoo yss :: IO [String], so hs :: [String].
let gs = rs ++ hs
return gs
As mentioned above, let just binds a name to a value, so we don't really need it here:
hoo :: [String] -> IO [String]
hoo (xs:ys:yss) = do
rs <- goo xs ys
hs <- hoo yss
return (rs ++ hs)
Alternatively, without do notation and <- we'd do it as follows.
(>>=) :: IO a -> (a -> IO b) -> IO b
>>= takes an IO value and a callback function, and it runs the function on the "unwrapped" value (a). That means within the function we get local access to the value as long as the result of the whole thing is IO b again (for some arbitrary type b).
hoo :: [String] -> IO [String]
hoo (xs : ys : yss) =
goo xs ys -- :: IO [String]
...
We have an IO [String] and we need to do something with [String], so we use >>=:
hoo :: [String] -> IO [String]
hoo (xs : ys : yss) =
goo xs ys >>= (\rs -> ...)
If you look at >>='s type signature, the role of a is played by [String] here
(rs :: [String]) and b is also [String] (because hoo as a whole needs to return IO [String]).
So what do we do in the ... part? We need to make a recursive call to hoo, which again results in an IO [String] value, so we use >>= again:
hoo :: [String] -> IO [String]
hoo (xs : ys : yss) =
goo xs ys >>= (\rs -> hoo yss >>= (\hs -> ...))
Again, hs :: [String] and ... better have type IO [String] to make the whole thing typecheck.
Now that we have rs :: [String] and hs :: [String], we can simply concatenate them:
hoo :: [String] -> IO [String]
hoo (xs : ys : yss) =
goo xs ys >>= (\rs -> hoo yss >>= (\hs -> rs ++ hs)) -- !
This is a type error. rs ++ hs :: [String], but the context requires IO [String]. Fortunately there's a function that can help us out:
return :: a -> IO a
Now it typechecks:
hoo :: [String] -> IO [String]
hoo (xs : ys : yss) =
goo xs ys >>= (\rs -> hoo yss >>= (\hs -> return (rs ++ hs)))
Due to the way Haskell syntax works (function bodies extend as far to the right as possible), most parens here are actually optional:
hoo :: [String] -> IO [String]
hoo (xs : ys : yss) =
goo xs ys >>= \rs -> hoo yss >>= \hs -> return (rs ++ hs)
And with a bit of reformatting the whole thing can be made to look pretty suggestive:
hoo :: [String] -> IO [String]
hoo (xs : ys : yss) =
goo xs ys >>= \rs ->
hoo yss >>= \hs ->
return (rs ++ hs)
do notation is very handy. Use it, it's your friend. We just need to follow its rules, were each thing going into its place must have a correct type, correspondingly.
You were very close:
goo :: String -> String -> IO [String]
{- hoo' :: [String] -> IO [String]
hoo' (xs:ys:yss) = do
rs <- goo xs ys
let gs = rs ++ hoo' yss
return gs -}
hoo'' :: [String] -> IO [String]
hoo'' (xs:ys:yss) = do
rs <- goo xs ys -- goo xs ys :: IO [String] -- rs :: [String]
qs <- hoo'' yss -- hoo'' yss :: IO [String] -- qs :: [String]
let gs = rs ++ qs -- gs :: [String]
return gs -- return gs :: IO [String]
In do notation, with x <- foo, when foo :: IO a, we have x :: a. That's it. (Some more explanations are e.g. here).
As for recursion, it is achieved with do notation just as it is achieved in pure code: by naming things, and referring to the same name from inside the expression defining that name, whether it is a pure expression or a do notation.
Recursion is a leap of faith. We don't care how the thing is defined -- we assume it is defined correctly so we can just refer to it by its name. As long as the types fit.
To do this with do notation, you need to bind the results of every IO action in order to use those results in pure expressions such as let rs =…++…, like so:
hoo :: [String] -> IO [String]
hoo (xs:ys:yss) = do
g <- goo xs ys
h <- hoo yss
let rs = g ++ h
return rs
However, often you don’t want to introduce a temporary name for the result of every action, so in typical Haskell code, there are a few combinators that make this kind of thing more compact. Here you can use liftA2:
liftA2
:: Applicative f
-- Given a pure function to combine an ‘a’ and a ‘b’ into a ‘c’…
=> (a -> b -> c)
-- An action that produces an ‘a’…
-> f a
-- And an action that produces a ‘b’…
-> f b
-- Make an action that produces a ‘c’.
-> f c
Like this:
hoo (xs:ys:yss) = liftA2 (++) (goo xs ys) (hoo yss)
liftA2 only works for functions of two arguments, though; for applying functions of other numbers of arguments, you can use the Functor operator <$> (an alias of fmap) and the Applicative operator <*>:
(<$>)
:: Functor f
-- Given a pure function to transform an ‘a’ into a ‘b’…
=> (a -> b)
-- And an action that produces an ‘a’…
-> f a
-- Make an action that produces a ‘b’.
-> f b
(<*>)
:: Applicative f
-- Given an action that produces a function from ‘a’ to ‘b’…
=> f (a -> b)
-- And an action that produces an ‘a’…
-> f a
-- Make an action that produces a ‘b’.
-> f b
These can be combined like so:
(++) <$> goo xs ys :: IO ([String] -> [String])
-- f (a -> b)
hoo yss :: IO [String]
-- f a
hoo (xs:ys:yss) = (++) <$> goo xs ys <*> hoo yss :: IO [String]
-- f b
That is, fmapping (++) over the result of goo xs ys using <$> is an action that returns a partially applied function, and <*> produces an action that applies this function to the result of hoo yss.
(There is a law which states that f <$> x is equivalent to pure f <*> x—that is, if you have an action pure f that just returns a function f, unwrap that action and apply it to the result of x using <*>, then that’s the same as just applying the pure function to the action with <$>.)
Another example of using this with a function of 3 arguments:
cat3 a b c = a ++ b ++ c
main = do
-- Concatenate 3 lines of input
result <- cat3 <$> getLine <*> getLine <*> getLine
putStrLn result
You can think of all of these combinators as different kinds of application operators, like ($):
($) :: (a -> b) -> a -> b
(<$>) :: (a -> b) -> f a -> f b
(<*>) :: f (a -> b) -> f a -> f b
(=<<) :: (a -> f b) -> f a -> f b
($) applies a pure function to a pure argument
(<$>) applies a pure function to the result of an action
(<*>) applies a pure function resulting from an action to the result of another action
(=<<) (the flipped version of (>>=)) applies a function returning an action to the result of an action

Funct symClosure issue

I'm not sure what this error message wants me to change as I can't see the issue with my code but clearly there's something wrong otherwise it would compile.
Error message:
* Couldn't match expected type `(a, a)' with actual type `[(a, a)]'
* In the expression: xs ++ (flips xs)
In the expression: [xs ++ (flips xs)]
In an equation for `symClosure': symClosure xs = [xs ++ (flips xs)]
* Relevant bindings include
xs :: [(a, a)]
symClosure :: [(a, a)] -> [(a, a)]
symClosure xs = [xs ++ (flips xs)]
Code:
heads :: (Eq a) => [(a,a)] -> [a]
heads xs = [x | (x, _) <- xs]
tails :: (Eq a) => [(a,a)] -> [a]
tails xs = [x | (_,x) <- xs]
flips :: [a] -> [(a,a)]
flips xs = tails xs ++ heads xs
symClosure :: (Eq a) => [(a,a)] -> [(a,a)]
symClosure xs = [xs ++ (flips xs)]
Side note: I can't import anything and I can't change signatures.
Again, any info to help me understand is very much appreciated :)
I think your flips does not do what its signature says it does:
heads :: (Eq a) => [(a,a)] -> [a]
tails :: (Eq a) => [(a,a)] -> [a]
(++) :: [a] -> [a] -> [a]
in other words, with your definition this signature is correct:
flips :: [(a, a)] -> [a]
flips xs = tails xs ++ heads xs
Note that you can only call tails and heads on lists of pairs. Also note you can leave out the Eq constraint from all the signatures above.
If you meant to reverse the tuples, you can use zip instead
flips :: [(a, a)] -> [(a, a)]
flips xs = tails xs `zip` heads xs
As for symClosure, taking the definition of flips above, the expression
symClosure xs = [xs ++ (flips xs)]
would produce a list with a single element, itself a list of pairs. That explains why it is saying that the (a, a) in your signature does not match the [(a, a)] it infers from the expression. You probably need to leave the brackets out.
symClosure xs = xs ++ flips xs

Reflexive Closure

I have been working on a question about reflexive closure:
The reflexive closure of a relation R is the smallest relation bigger than R which is reflexive. In other words, it is R with whatever pairs added to make R reflexive. Write a function (reflClosure) which takes a list of pairs (standing for R) and returns a list of pairs which is the reflexive closure of R. You do not need to worry about the order in which pairs appear in your return value.
I came up with this solution but it seems quite sloppy and lack neatness.
-- QUESTION 2: Functions and relations
reflClosure :: (Eq a) => [(a,a)] -> [(a,a)]
reflClosure (x:xs) = nub ( (x:xs) ++ [ (x,x) | x <- (heads (x:xs)) ++ (tails
(x:xs)) ])
nub :: Eq a => [a] -> [a]
nub = nubBy (==)
nubBy :: (a -> a -> Bool) -> [a] -> [a]
nubBy eq [] = []
nubBy eq (x:xs) = x : nubBy eq (filter (\y -> not (eq x y)) xs)
heads :: (Eq a) => [(a,a)] -> [a]
heads list = nub [x | (x, _) <- list]
tails :: (Eq a) => [(a,a)] -> [a]
tails list = nub [x | (_,x) <- list]
exists :: (Eq a) => (a,a) -> [(a,a)] -> Bool
exists x xs = length (filter (==x) xs) > 0
-- TEST SET FOR Q2
{-
Your functions should have the following behaviour:
reflClosure [(1,2),(3,2)] = [(1,2),(3,2),(1,1),(2,2),(3,3)]
reflClosure [(1,1),(3,5)] = [(1,1),(3,5),(3,3),(5,5)]
DO NOT WORRY ABOUT THE ORDER IN WHICH PAIRS APPEAR IN YOUR LIST
-}
Is there an easier way to do this? Explanation would be incredibly useful to learn from as well.
A nicer way to write heads and tails is the following:
heads :: (Eq a) => [(a,a)] -> [a]
heads = nub . map fst
tails :: (Eq a) => [(a,a)] -> [a]
tails = nub . map snd
It's point-free, plus it uses the more "functional" map rather than a list comprehension.
However, the fact that you need both means there's an even nicer way:
(heads (x:xs), tails (x:xs)) = (\(a,b) -> (nub a) (nub b)) $ unzip (x:xs)
Getting the fsts and the snds is equivalent to an unzip.
Also, you can simplify the signature of exists:
exists :: (Eq a) => a -> [a] -> Bool
exists x xs = length (filter (==x) xs) > 0
since nothing depends on the input being a list of pairs.
Data.List already defines nubBy, so I'm not sure why you've defined it there.
It's not clear why you've defined reflClosure to match on (x:xs), because all you care about (apparently) is that the list is non-empty. Perhaps something like this:
reflClosure :: (Eq a) => [(a,a)] -> [(a,a)]
reflClosure [] = []
reflClosure xs =
let (as,bs) = unzip xs
in nub $ xs ++ [ (x,x) | x <- (nub as) ++ (nub bs) ]
Relations are isomorphic to sets of pairs, not lists of pairs, so it makes sense to model them as such. Note that all the Ord constraints below are there because the implementation of Set needs it.
Use the standard library sets because they are fast.
import Data.Set (Set)
import qualified Data.Set as Set
A type synonym to make the code easier to read:
-- A relation with underlying set s
type Relation s = Set (s,s)
Now we can write a function that gets all the members of the underlying set:
underlyingMembers :: Ord a => Relation a -> Set a
underlyingMembers r = (Set.map fst r) `Set.union` (Set.map snd r)
Once we have that, finding the reflexive closure of a relation is easy:
reflexiveClosure :: Ord a => Relation a -> Relation a
reflexiveClosure r = r `Set.union` (Set.map (\x -> (x,x)) (underlyingMembers r)
If you really need to work with lists, (you really shouldn't, though) you can fromList/toList:
listVersion :: Ord a => [(a,a)] -> [(a,a)]
listVersion = Set.toList . reflexiveClosure . Set.fromList
If any of this is unclear, please leave a comment and I will explain more in detail.

Filter an infinite list of monadic values

Perhaps this is obvious, but I can't seem to figure out how to best filter an infinite list of IO values. Here is a simplified example:
infinitelist :: [IO Int]
predicate :: (a -> Bool)
-- how to implement this?
mysteryFilter :: (a -> Bool) -> [IO a] -> IO [a]
-- or perhaps even this?
mysteryFilter' :: (a -> Bool) -> [IO a] -> [IO a]
Perhaps I have to use sequence in some way, but I want the evaluation to be lazy. Any suggestions? The essence is that for each IO Int in the output we might have to check several IO Int values in the input.
Thank you!
Not doable without using unsafeInterleaveIO or something like it. You can't write a filter with the second type signature, since if you could you could say
unsafePerformIOBool :: IO Bool -> Bool
unsafePerformIOBool m = case mysteryFilter' id [m] of
[] -> False
(_:_) -> True
Similarly, the first type signature isn't going to work--any recursive call will give you back something of type IO [a], but then to build a list out of this you will need to perform this action before returning a result (since : is not in IO you need to use >>=). By induction you will have to perform all the actions in the list (which takes forever when the list is infinitely long) before you can return a result.
unsafeInterleaveIO resolves this, but is unsafe.
mysteryFilter f [] = return []
mysteryFilter f (x:xs) = do ys <- unsafeInterleaveIO $ mysteryFilter f xs
y <- x
if f y then return (y:ys) else return ys
the problem is that this breaks the sequence that the monad is supposed to provide. You no longer have guarantees about when your monadic actions happen (they might never happen, they might happen multiple times, etc).
Lists just do not play nice with IO. This is why we have the plethora of streaming types (Iteratees, Conduits, Pipes, etc).
The simplest such type is probably
data MList m a = Nil | Cons a (m (MList m a))
note that we observe that
[a] == MList Id a
since
toMList :: [a] -> MList Id a
toMList [] = Nil
toMList (x:xs) = Cons x $ return $ toMList xs
fromMList :: MList Id a -> [a]
fromMList Nil = []
fromMList (Cons x xs) = x:(fromMList . runId $ xs)
also, MList is a functor
instance Functor m => Functor (MList m) where
fmap f Nil = Nil
fmap f (Cons x xs) = Cons (f x) (fmap (fmap f) xs)
and it is a functor in the category of Functor's and Natural transformations.
trans :: Functor m => (forall x. m x -> n x) -> MList m a -> MList n a
trans f Nil = Nil
trans f (Cons x xs) = Cons x (f (fmap trans f xs))
with this it is easy to write what you want
mysteryFilter :: (a -> Bool) -> MList IO (IO a) -> IO (MList IO a)
mysteryFilter f Nil = return Nil
mysteryFilter f (Cons x xs)
= do y <- x
let ys = liftM (mysteryFilter f) xs
if f y then Cons y ys else ys
or various other similar functions.

Pattern matching against a tuple in the IO Monad in Haskell

I've been studying Haskell in my spare time and have recently crossed into the area of monadic functions. I've distilled the code from an excercise I've been working on into this very contrived example to isolate the exact problem I'm having:
import System.Random
rndPermu :: [a] -> IO (a, [a])
rndPermu xs = (front, back)
where (front, back) = hurf xs
hurf :: [a] -> IO (a, [a])
hurf xs = randomRIO (0, (length xs) - 1) >>= \r -> return $ removeAt r xs
removeAt :: Int -> [a] -> (a, [a])
removeAt n xs = (e, rest)
where e = xs !! n
rest = take n xs ++ (tail $ drop n xs)
rndPermu produces a type error when loaded into GHCi stating a type (t, t1) was expected in the 'where' clause but IO (a, [a]) was received. I can use things like (liftM fst) to pull individual items from the tuple and just assign a single value but that's obviously a sloppy and roundabout way of going about things. I feel I'm probably stumbling over some minor nuance of syntax that's staring me in the face. How does one resolve this type error? It should be possible to directly match against a tuple wrapped in a monad, shouldn't it?
I don't know why you don't have
rndPermu xs = hurf xs
but to answer the question you asked, try this
rndPermu xs = do (front, back) <- hurf xs
return (front, back)
My understanding is that you cannot directly match something within IO. You have to extract it first using the <- syntax.
If I understand correctly what you are trying to do, rndPermu tries to take the value in IOreturned by hurf and remove the IO from it, like rndPermu :: IO a -> a. This is not possible. A return value in the IO monad signals that the hurf function uses IO and all functions that use the results of a call to hurf will therefore indirectly also use IO: Their return values should also be in the IO monad. This is enforced by the type system.
If you just want to use pattern matching in a monad the most direct way is to use the do-notation:
rndPermu :: [a] -> IO (a, [a])
rndPermu xs =
do (front, back) <- hurf xs
return (front, back)
A common pattern is to use different, pure functions to do further processing of values.
These functions are just called from IO or a different monad, but they don't need to know about that:
-- pure function to do something with the result of |hurf|
modify :: (a, [a]) -> (a, [a])
modify (a, as) = (a, reverse as)
rndPermu :: [a] -> IO (a, [a])
rndPermu xs =
do r <- hurf xs
return (modify r)
-- or, with >>= operator:
-- hurf xs >>= return . modify
As an alternative to a do block, you can pattern match in the function to which you bind the monadic value:
rndPermu xs = hurf xs >>= \(front, back) -> return (front, back)
rndPermu xs = hurf xs >>= \res -> case res of (front, back) -> return (front, back)
To answer the question from your comment, GHCi does infer that rndPermu should have an IO type. That's not the problem. The problem is this line:
where (front, back) = hurf xs
Type inference just means (loosely) that you don't have to specify the types of the expressions you're dealing with. Type inference does not mean that Haskell will simply convert values of one type to another silently; quite the opposite in fact. As others mentioned, you don't have to write a do block if you don't want to, but you do have to deal with the fact that you have an IO value.

Resources