I have the following sample code
let x = [return 1::IO(Int), return 2::IO(Int)]
So x is a list of IO(Int)s.
maximum is a function which returns the maximum of a list, if the things in the list are Ords.
How do I "map" maximum to run on this list of IO(Int)s?
First sequence the array into IO [Int] and then run maximum on it using liftM:
liftM maximum (sequence yourList) :: IO Int
The key point here is that you cannot compare IO actions, only the values
that result from those actions. To perform the comparison, you have to perform
those actions to get back a list of the results. Fortunately, there is
a function that does just that: sequence :: (Monad m) => [m a] -> m [a].
This takes a list of actions and performs them in order to produce an action
that gives a list of results.
To compute the maximum, you would do something like
x = [return 1::IO(Int), return 2::IO(Int)]
...
biggest = maximum `fmap` sequence x :: IO [Int]
Related
I want to generate an increasing number of lists i.e.
prelude>sample' incList
[[],[19],[6,110],[24,67,81]....]
How should I use vectorOf?
incList:: Gen [Integer]
incList=
do x<-vectorOf [0..] arbitrary
return x
I cant think of a way to just take out the first number from the list one at a time :/ Maybe something with fmap take 1, I dunno..
I think you here aim to do too much at once. Let us first construct a generator for a random list of Ordered objects with a given length in ascending order:
import Data.List(sort)
incList :: (Arbitrary a, Ord a) => Int -> Gen [a]
incList n = fmap sort (vectorOf n arbitrary)
Now we can construct a Generator that generates an endless list of lists by each time incrementing the size with one:
incLists :: (Arbitrary a, Ord a) => Gen [[a]]
incLists = mapM incList [0..]
We can then generate values from this Generator with generate :: Gen a -> IO [a]:
Prelude File> generate incLists :: IO [[Int]]
[[],[-19],[6,25],[-19,-14,15],[-4,6,20,28],[-23,-19,-6,-1,22],[-29,-21,-13,-9,-9,15],[-23,-15,-4,3,3,27,27],[-29,-29,-26,-25,18,19,23,27],[-24,-23,-16,-14,0,13,17,17,23],[-29,-15,-12,-4,-1,1,2,20,22,26],[-26,-24,-22,-16,-12,5,5,10,11,25,29],[-29,-28,-20,-14,-9,-7,-3,14,15,20,26,28],...]
Is there a way to write do notation for a monad in a function which the return type isn't of said monad?
I have a main function doing most of the logic of the code, supplemented by another function which does some calculations for it in the middle. The supplementary function might fail, which is why it is returning a Maybe value. I'm looking to use the do notation for the returned values in the main function. Giving a generic example:
-- does some computation to two Ints which might fail
compute :: Int -> Int -> Maybe Int
-- actual logic
main :: Int -> Int -> Int
main x y = do
first <- compute x y
second <- compute (x+2) (y+2)
third <- compute (x+4) (y+4)
-- does some Int calculation to first, second and third
What I intend is for first, second, and third to have the actual Int values, taken out of the Maybe context, but doing the way above makes Haskell complain about not being able to match types of Maybe Int with Int.
Is there a way to do this? Or am I heading towards the wrong direction?
Pardon me if some terminology is wrongly used, I'm new to Haskell and still trying to wrap my head around everything.
EDIT
main has to return an Int, without being wrapped in Maybe, as there is another part of the code using the result of mainas Int. The results of a single compute might fail, but they should collectively pass (i.e. at least one would pass) in main, and what I'm looking for is a way to use do notation to take them out of Maybe, do some simple Int calculations to them (e.g. possibly treating any Nothing returned as 0), and return the final value as just Int.
Well the signature is in essence wrong. The result should be a Maybe Int:
main :: Int -> Int -> Maybe Int
main x y = do
first <- compute x y
second <- compute (x+2) (y+2)
third <- compute (x+4) (y+4)
return (first + second + third)
For example here we return (first + second + third), and the return will wrap these in a Just data constructor.
This is because your do block, implicitly uses the >>= of the Monad Maybe, which is defined as:
instance Monad Maybe where
Nothing >>=_ = Nothing
(Just x) >>= f = f x
return = Just
So that means that it will indeed "unpack" values out of a Just data constructor, but in case a Nothing comes out of it, then this means that the result of the entire do block will be Nothing.
This is more or less the convenience the Monad Maybe offers: you can make computations as a chain of succesful actions, and in case one of these fails, the result will be Nothing, otherwise it will be Just result.
You can thus not at the end return an Int instead of a Maybe Int, since it is definitely possible - from the perspective of the types - that one or more computations can return a Nothing.
You can however "post" process the result of the do block, if you for example add a "default" value that will be used in case one of the computations is Nothing, like:
import Data.Maybe(fromMaybe)
main :: Int -> Int -> Int
main x y = fromMaybe 0 $ do
first <- compute x y
second <- compute (x+2) (y+2)
third <- compute (x+4) (y+4)
return (first + second + third)
Here in case the do-block thus returns a Nothing, we replace it with 0 (you can of course add another value in the fromMaybe :: a -> Maybe a -> a as a value in case the computation "fails").
If you want to return the first element in a list of Maybes that is Just, then you can use asum :: (Foldable t, Alternative f) => t (f a) -> f a, so then you can write your main like:
-- first non-failing computation
import Data.Foldable(asum)
import Data.Maybe(fromMaybe)
main :: Int -> Int -> Int
main x y = fromMaybe 0 $ asum [
compute x y
compute (x+2) (y+2)
compute (x+4) (y+4)
]
Note that the asum can still contain only Nothings, so you still need to do some post-processing.
Willem's answer is basically perfect, but just to really drive the point home, let's think about what would happen if you could write something that allows you to return an int.
So you have the main function with type Int -> Int -> Int, let's assume an implementation of your compute function as follows:
compute :: Int -> Int -> Maybe Int
compute a 0 = Nothing
compute a b = Just (a `div` b)
Now this is basically a safe version of the integer division function div :: Int -> Int -> Int that returns a Nothing if the divisor is 0.
If you could write a main function as you like that returns an Int, you'd be able to write the following:
unsafe :: Int
unsafe = main 10 (-2)
This would make the second <- compute ... fail and return a Nothing but now you have to interpret your Nothing as a number which is not good. It defeats the whole purpose of using Maybe monad which captures failure safely. You can, of course, give a default value to Nothing as Willem described, but that's not always appropriate.
More generally, when you're inside a do block you should just think inside "the box" that is the monad and don't try to escape. In some cases like Maybe you might be able to do unMaybe with something like fromMaybe or maybe functions, but not in general.
I have two interpretations of your question, so to answer both of them:
Sum the Maybe Int values that are Just n to get an Int
To sum Maybe Ints while throwing out Nothing values, you can use sum with Data.Maybe.catMaybes :: [Maybe a] -> [a] to throw out Nothing values from a list:
sum . catMaybes $ [compute x y, compute (x+2) (y+2), compute (x+4) (y+4)]
Get the first Maybe Int value that's Just n as an Int
To get the first non-Nothing value, you can use catMaybes combined with listToMaybe :: [a] -> Maybe a to get Just the first value if there is one or Nothing if there isn't and fromMaybe :: a -> Maybe a -> a to convert Nothing to a default value:
fromMaybe 0 . listToMaybe . catMaybes $ [compute x y, compute (x+2) (y+2), compute (x+4) (y+4)]
If you're guaranteed to have at least one succeed, use head instead:
head . catMaybes $ [compute x y, compute (x+2) (y+2), compute (x+4) (y+4)]
How can I generate random array using Data.Array?
I have function, that gives me a random number:
randomNumber :: (Random r) => r -> r -> IO r
randomNumber a b = getStdRandom (randomR (a,b))
And then I'm trying to use function from Data.Array to generate list
assocs $ array (1,100) [(i,i) | i <- (randomNumber 1 10)]
I know, that the type of randomNumber is IO, is there any method to convert IO Int -> Int? Or I need to use other methods to get random list? Should I do these functions with bind operator in do block?
You should use functions to generate random list from a generator, that are pure, and then use getStdRandom:
randomList :: Int -> Int -> IO [Int]
randomList a b = getStdGen >>= return . randomRs (a,b)
The function that you need is randomRs. Then you set the generator to stdGen with getStdGen and you have your generator.
The function randomList first gets the standard generator with getStdGen and then passes it to randomRs. Note that randomList can be rewritten without hiding the generator parameter:
randomList a b = getStdGen >>= \gen -> return (randomRs (a,b) gen)
I'll continue as long as #mariop's answer tells about lists, not arrays, and try to explain a nature of Haskell randomness a little more.
(if you're not interested in theory, skip to the (tl;dr) section)
At first, let's choose a signature for our presumed function. I'll consider that you need a plain array (as in C or Java), indexed by consecutive natural numbers (if my guessing is wrong, please correct).
As you may know, all Haskell functions are pure and deterministic, so each function must always return same results for the same arguments. That's not the case of random, of course. The solution is to use pseudorandom values, where we have a generator. A generator itself is a complicated function that have an internal hidden state called seed, and can produce a value and a new generator with a new seed (which then can produce a new (value, generator) pair and so on). A good generator is built in way that the next value could not be predicted from the previous value (when the we don't know the seed), so they appear as random to the user.
In fact, all major random implementations in most languages are
pseudorandom because the "true" random (which gets its values from the
sources of "natural" randomness, called entropy, such as CPU temperature) is
computatively expensive.
All so-called random functions in Haskell are dealing with the generator in some way. If you look at methods from the Random typeclass, they are divided in two groups:
Those which get the random generator explicitly: randomR, random and so on. You can build an explicit generator, initialized with a seed, with mkStdRandom (or even make your own).
Those which work in the IO monad: randomIO, randomRIO. They actually get the generator from the environment "carried" within the IO monad (with getStdRandom), and give it to function from the first group.
So, we can organize our function in either way:
--Arguments are generator, array size, min and max bound
generateArray :: (RangomGen g, Random r) => g -> Int -> r -> r -> Array Int r
or
--Arguments are array size, min and max bound
generateArray :: Random r => Int -> r -> r -> IO (Array Int r)
Because Haskell is lazy, there is no need to make a fixed set of random values — we can make an infinite one and take as many values as we need. The infinite list of random bounded values is produced by the randomRs function.
(tl;dr)
If the array is consecutive, the easier way is to build it from a plain values list rather than assocs (key, value) list:
generateArray gen size min max =
listArray (0, size - 1) $ randomRs (min, max) gen
or
generateArray size min max =
getStdGen >>= return . listArray (0, size - 1) . randomRs (min, max)
I am doing a haskell exercise, regarding define a function accumulate :: [IO a] -> IO [a]
which performs a sequence of interactions and accumulates their result in a list.
What makes me confused is how to express a list of IO a ? (action:actions)??
how to write recursive codes using IO??
This is my code, but these exists some problem...
accumulate :: [IO a] -> IO [a]
accumulate (action:actions) = do
value <- action
list <- accumulate (action:actions)
return (convert_to_list value list)
convert_to_list:: Num a =>a -> [a]-> [a]
convert_to_list a [] = a:[]
convert_to_list x xs = x:xs
What you are trying to implement is sequence from Control.Monad.
Just to let you find the answer instead of giving it, try searching for [IO a] -> IO [a] on hoogle (there's a Source link on the right hand side of the page when you've chosen a function).
Try to see in your code what happens when list of actions is empty list and see what does sequence do to take care of that.
There is already such function in Control.Monad and it called sequence (no you shouldn't look at it). You should denote the important decision taken during naming of it. Technically [IO a] says nothing about in which order those Monads should be attached to each other, but name sequence puts a meaning of sequential attaching.
As for the solving you problem. I'd suggest to look more at types and took advice of #sacundim. In GHCi (interpreter from Glasgow Haskell Compiler) there is pretty nice way to check type and thus understand expression (:t (:) will return (:) :: a -> [a] -> [a] which should remind you one of you own function but with less restrictive types).
First of all I'd try to see at what you have showed with more simple example.
data MyWrap a = MyWrap a
accumulate :: [MyWrap a] -> MyWrap [a]
accumulate (action:actions) = MyWrap (convert_to_list value values) where
MyWrap value = action -- use the pattern matching to unwrap value from action
-- other variant is:
-- value = case action of
-- MyWrap x -> x
MyWrap values = accumulate (action:actions)
I've made the same mistake that you did on purpose but with small difference (values is a hint). As you probably already have been told you could try to interpret any of you program by trying to inline appropriate functions definitions. I.e. match definitions on the left side of equality sign (=) and replace it with its right side. In your case you have infinite cycle. Try to solve it on this sample or your and I think you'll understand (btw your problem might be just a typo).
Update: Don't be scary when your program will fall in runtime with message about pattern match. Just think of case when you call your function as accumulate []
Possibly you looking for sequence function that maps [m a] -> m [a]?
So the short version of the answer to your question is, there's (almost) nothing wrong with your code.
First of all, it typechecks:
Prelude> let accumulate (action:actions) = do { value <- action ;
list <- accumulate (action:actions) ; return (value:list) }
Prelude> :t accumulate
accumulate :: (Monad m) => [m t] -> m [t]
Why did I use return (value:list) there? Look at your second function, it's just (:). Calling g
g a [] = a:[]
g a xs = a:xs
is the same as calling (:) with the same arguments. This is what's known as "eta reduction": (\x-> g x) === g (read === as "is equivalent").
So now just one problem remains with your code. You've already taken a value value <- action out of the action, so why do you reuse that action in list <- accumulate (action:actions)? Do you really have to? Right now you have, e.g.,
accumulate [a,b,c] ===
do { v1<-a; ls<-accumulate [a,b,c]; return (v1:ls) } ===
do { v1<-a; v2<-a; ls<-accumulate [a,b,c]; return (v1:v2:ls) } ===
do { v1<-a; v2<-a; v3<-a; ls<-accumulate [a,b,c]; return (v1:v2:v3:ls) } ===
.....
One simple fix and you're there.
I have a Haskell function that returns a monad, declared as follows:
data Options = Options {
optGames :: Int,
optSuits :: Int,
optVerbose :: Bool
} deriving Show
playGame :: Options -> StateT StdGen (WriterT [String] IO)) Bool
This function plays a single game of solitaire, then returns a boolean indicating a win or loss, along with a log in the WriterT monad.
I would like to call this function a set number of times, each time using the "next" value of the random generator (StdGen), and concatenating the Bool return values into a list.
I tried creating a recursive function to do the calls, but can't figure out how to pass the monad into each next iteration.
I would like to emulate
initial state >>= playGame >>= playGame ... -- repeat N times
and collect all of the resulting Bool values, as well as the log entries from the WriterT monad.
What is the best way to do this?
I think you're looking for replicateM. This repeats the given action a specified number of times, returning the result as a list. So replicateM n playGame corresponds to playing the game n times and getting a list of the results back.