Haskell: Monad return list - haskell

I'm trying to write some code in Haskell and there is problem that i can't solve
f 0 = []
f n = do
x <- [0..4]
y <- x:(f (n-1))
return y
The output is:
[0,0,0,1,2,3,4,1,0,1,2,3,4,2,0,1,2,3,4,3,0,1,2,3,4,4,0,1,2,3,4,1,0,0,1,2,3,4,1,0,1,2,3,4,2,0,1,2,3,4,3,0,1,2,3,4,4,0,1,2,3,4,2,0,0,1,2,3,4,1,0,1,2,3,4,2,0,1,2,3,4,3,0,1,2,3,4,4,0,1,2,3,4,3,0,0,1,2,3,4,1,0,1,2,3,4,2,0,1,2,3,4,3,0,1,2,3,4,4,0,1,2,3,4,4,0,0,1,2,3,4,1,0,1,2,3,4,2,0,1,2,3,4,3,0,1,2,3,4,4,0,1,2,3,4]
but I need it to be:
[[0,0,0],[0,0,1],[0,0,2],[0,0,3],[0,0,4],[0,1,0],[0,1,1]...
Any ideas?

Others have already answered, but you may wish to know there's already a function like yours in the standard library:
> import Control.Monad
> replicateM 3 [0..4]
[[0,0,0],[0,0,1],[0,0,2],[0,0,3],[0,0,4],[0,1,0],[0,1,1], ...

So you want the elements of your final list to be lists themselves ?
In the List monad, each <- remove one enclosing from the type, in other words :
(x :: a) <- (xs :: [a])
So it is clear that x :: Int in your code. And you wish for your function to return [[Int]] so what should be the type of x:(f (n-1)) ? You see that this expression shouldn't typecheck if f type was correct so there is your problem : you don't want to cons x to the result of f (n-1) but to each of the results of f (n-1) thus :
f n = do
x <- [0..4]
xs <- f (n-1)
return (x : xs)
If you try this you should see it doesn't work, this is because your f 0 should contain one possibility :
f 0 = return [] -- or [[]]

Let's desugar first:
f 0 = []
f n = [0 .. 4] >>= \x -> x : (f (n - 1)) >>= \y -> return y
Note
xs >>= f = concat (map f xs)
[0..4] >>= \x -> x : (f (n - 1)) will simply return [0..4] when n is 1. However, it need to be [[0], [1], [2], [3], [4]],
Thus, the following will do:
f 0 = [[]]
f n = [0 .. 4] >>= \x -> map (x:) (f (n - 1)) >>= \y -> return y

cross = do
x <- [0..4]
y <- [0..4]
z <- [0..4]
return [x,y,z]

Related

Using foldr to define map (develop)

Having a hard time understanding fold... Is the expansion correct ? Also would appreciate any links, or analogies that would make fold more digestible.
foldMap :: (a -> b) -> [a] -> [b]
foldMap f [] = []
foldMap f xs = foldr (\x ys -> (f x) : ys) [] xs
b = (\x ys -> (f x):ys)
foldMap (*2) [1,2,3]
= b 1 (b 2 (foldr b [] 3))
= b 1 (b 2 (b 3 ( b [] [])))
= b 1 (b 2 ((*2 3) : []))
= b 1 ((*2 2) : (6 :[]))
= (* 2 1) : (4 : (6 : []))
= 2 : (4 : (6 : []))
First, let's not use the name foldMap since that's already a standard function different from map. If you want to re-implement an existing function with the same or similar semantics, convention is to give it the same name but either in a separate module, or with a prime ' appended to the name. Also, we can omit the empty-list case, since you can just pass that to the fold just as well:
map' :: (a -> b) -> [a] -> [b]
map' f xs = foldr (\x ys -> f x : ys) [] xs
Now if you want to evaluate this function by hand, first just use the definition without inserting anything more:
map' (*2) [1,2,3,4]
≡ let f = (*2)
xs = [1,2,3,4]
in foldr (\x ys -> (f x) : ys) [] xs
≡ foldr (\x ys -> (*2) x : ys) [] [1,2,3,4]
Now just prettify a bit:
≡ foldr (\x ys -> x*2 : ys) [] [1,2,3,4]
Now to evaluate this through, you also need the definition of foldr. It's actually a bit different in GHC, but effectively
foldr _ z [] = z
foldr f z (x:xs) = f x (foldr f z xs)
So with your example
...
≡ foldr (\x ys -> x*2 : ys) [] (1:[2,3,4])
≡ (\x ys -> x*2 : ys) 1 (foldr (\x ys -> x*2 : ys) [] [2,3,4])
Now we can perform a β-reduction:
≡ 1*2 : foldr (\x ys -> x*2 : ys) [] [2,3,4]
≡ 2 : foldr (\x ys -> x*2 : ys) [] [2,3,4]
...and repeat for the recursion.
foldr defines a family of equations,
foldr g n [] = n
foldr g n [x] = g x (foldr g n []) = g x n
foldr g n [x,y] = g x (foldr g n [y]) = g x (g y n)
foldr g n [x,y,z] = g x (foldr g n [y,z]) = g x (g y (g z n))
----- r ---------
and so on. g is a reducer function,
g x r = ....
accepting as x an element of the input list, and as r the result of recursively processing the rest of the input list (as can be seen in the equations).
map, on the other hand, defines a family of equations
map f [] = []
map f [x] = [f x] = (:) (f x) [] = ((:) . f) x []
map f [x,y] = [f x, f y] = ((:) . f) x (((:) . f) y [])
map f [x,y,z] = [f x, f y, f z] = ((:) . f) x (((:) . f) y (((:) . f) z []))
= (:) (f x) ( (:) (f y) ( (:) (f z) []))
The two families simply exactly match with
g = ((:) . f) = (\x -> (:) (f x)) = (\x r -> f x : r)
and n = [], and thus
foldr ((:) . f) [] xs == map f xs
We can prove this rigorously by mathematical induction on the input list's length, following the defining laws of foldr,
foldr g n [] = []
foldr g n (x:xs) = g x (foldr g n xs)
which are the basis for the equations at the top of this post.
Modern Haskell has Fodable type class with its basic fold following the laws of
fold(<>,n) [] = n
fold(<>,n) (xs ++ ys) = fold(<>,n) xs <> fold(<>,n) ys
and the map is naturally defined in its terms as
map f xs = foldMap (\x -> [f x]) xs
turning [x, y, z, ...] into [f x] ++ [f y] ++ [f z] ++ ..., since for lists (<>) == (++). This follows from the equivalence
f x : ys == [f x] ++ ys
This also lets us define filter along the same lines easily, as
filter p xs = foldMap (\x -> [x | p x]) xs
To your specific question, the expansion is correct, except that (*2 x) should be written as ((*2) x), which is the same as (x * 2). (* 2 x) is not a valid Haskell (though valid Lisp :) ).
Functions like (*2) are known as "operator sections" -- the missing argument goes into the empty slot: (* 2) 3 = (3 * 2) = (3 *) 2 = (*) 3 2.
You also asked for some links: see e.g. this, this and this.

How to apply a function to a specific element of a list

How can I apply a function to only a single element of a list?
Any suggestion?
Example:
let list = [1,2,3,4,3,6]
function x = x * 2
in ...
I want to apply function only to the first occurance of 3 and stop there.
Output:
List = [1,2,6,4,3,6] -- [1, 2, function 3, 4, 3, 6]
To map or not to map, that is the question.
Better not to map.
Why? Because map id == id anyway, and you only want to map through one element, the first one found to be equal to the argument given.
Thus, split the list in two, change the found element, and glue them all back together. Simple.
See: span :: (a -> Bool) -> [a] -> ([a], [a]).
Write: revappend (xs :: [a]) (ys :: [a]) == append (reverse xs) ys, only efficient.
Or fuse all the pieces together into one function. You can code it directly with manual recursion, or using foldr. Remember,
map f xs = foldr (\x r -> f x : r) [] xs
takeWhile p xs = foldr (\x r -> if p x then x : r else []) [] xs
takeUntil p xs = foldr (\x r -> if p x then [x] else x : r) [] xs
filter p xs = foldr (\x r -> if p x then x : r else r) [] xs
duplicate xs = foldr (\x r -> x : x : r) [] xs
mapFirstThat p f xs = -- ... your function
etc. Although, foldr won't be a direct fit, as you need the combining function of the (\x xs r -> ...) variety. That is known as paramorphism, and can be faked by feeding tails xs to the foldr, instead.
you need to maintain some type of state to indicate the first instance of the value, since map will apply the function to all values.
Perhaps something like this
map (\(b,x) -> if (b) then f x else x) $ markFirst 3 [1,2,3,4,3,6]
and
markFirst :: a -> [a] -> [(Boolean,a)]
markFirst a [] = []
markFirst a (x:xs) | x==a = (True,x): zip (repeat False) xs
| otherwise = (False,x): markFirst a xs
I'm sure there is an easier way, but that's the best I came up with at this time on the day before Thanksgiving.
Here is another approach based on the comment below
> let leftap f (x,y) = f x ++ y
leftap (map (\x -> if(x==3) then f x else x)) $ splitAt 3 [1,2,3,4,3,6]
You can just create a simple function which multiples a number by two:
times_two :: (Num a) => a -> a
times_two x = x * 2
Then simply search for the specified element in the list, and apply times_two to it. Something like this could work:
map_one_element :: (Eq a, Num a) => a -> (a -> a) -> [a] -> [a]
-- base case
map_one_element _ _ [] = []
-- recursive case
map_one_element x f (y:ys)
-- ff element is found, apply f to it and add rest of the list normally
| x == y = f y : ys
-- first occurence hasnt been found, keep recursing
| otherwise = y : map_one_element x f ys
Which works as follows:
*Main> map_one_element 3 times_two [1,2,3,4,3,6]
[1,2,6,4,3,6]

Two implementations for List Monad bind in the literature: why are they equivalent?

Reading the Monad chapter in "Programming in Haskell" 2nd ed. from Graham Hutton, I found this example on page 167 to illustrate the behaviour of the List Monad:
> pairs [1,2] [3,4]
[(1,3),(1,4),(2,3),(2,4)]
With pairs defined like this:
pairs :: [a] -> [b] -> [(a,b)]
pairs xs ys = do x <- xs
y <- ys
return (x,y)
And this implementation of bind:
instance Monad [] where
-- (>>=) :: [a] -> (a -> [b]) -> [b]
xs >>= f = [y | x <- xs, y <- f x]
I tried to understand with pencil and paper how the example worked out, but didn't get it.
Then I found, that in other books the bind operation is defined differently:
...
xs >>= f = concat (fmap f xs)
With this definition I understand why the example works.
But the first definition is the one I found on hackage in the prelude, so I trust its correct.
My question:
Can anybody explain why the first definition is equivalent to the second? (Where does the concat-stuff happen in the first one?)
List comprehensions are just syntactic sugar. Basically, [f x y | x<-l, y<-m] is sugar for
concatMap (\x -> concatMap (\y -> return $ f x y) m) l
or equivalently
concat $ fmap (\x -> concat $ fmap (\y -> return $ f x y) m) l
thus the two implementations are indeed equivalent by definition.
Anyway you can of course manually evaluate the example from the comprehension-based definition, using “intuitive set comprehension” evaluation:
pairs [1,2] [3,4]
≡ do { x <- [1,2]; y <- [3,4]; return (x,y) }
≡ [1,2] >>= \x -> [3,4] >>= \y -> return (x,y)
≡ [p | x<-[1,2], p <- (\ξ -> [3,4] >>= \y -> return (ξ,y)) x]
≡ [p | x<-[1,2], p <- ([3,4] >>= \y -> return (x,y))]
≡ [p | x<-[1,2], p <- [q | y<-[3,4], q <- (\υ -> return (x,υ)) y]]
≡ [p | x<-[1,2], p <- [q | y<-[3,4], q <- return (x,y)]]
≡ [p | x<-[1,2], p <- [q | y<-[3,4], q <- [(x,y)]]]
≡ [p | x<-[1,2], p <- [(x,3), (x,4)]]
≡ [(1,3), (1,4)] ++ [(2,3), (2,4)]
≡ [(1,3), (1,4), (2,3), (2,4)]
[y | x <- xs, y <- f x] takes all the xs in xs one-by-one and
apply f to them, which is a monadic action a -> [a], thus the result is a list of values ([a])
the comprehension proceeds to address each y in f x one-by-one
each y is sent to the output list
this is equivalent to first mapping f over each of the elements of the input list, resulting in a list of nested lists, that are then concatenated. Notice that fmap is map for lists, and you could use concatMap f xs as the definition of xs >>= f.

get all possible combinations of k elements from a list

I need a function that does the same thing as itertools.combinations(iterable, r) in python
So far I came up with this:
{-| forward application -}
x -: f = f x
infixl 0 -:
{-| combinations 2 "ABCD" = ["AB","AC","AD","BC","BD","CD"] -}
combinations :: Ord a => Int -> [a] -> [[a]]
combinations k l = (sequence . replicate k) l -: map sort -: sort -: nub
-: filter (\l -> (length . nub) l == length l)
Is there a more elegant and efficient solution?
xs elements taken n by n is
mapM (const xs) [1..n]
all combinations (n = 1, 2, ...) is
allCombs xs = [1..] >>= \n -> mapM (const xs) [1..n]
if you need without repetition
filter ((n==).length.nub)
then
combinationsWRep xs n = filter ((n==).length.nub) $ mapM (const xs) [1..n]
(Based on #JoseJuan's answer)
You can also use a list comprehension to filter out those where the second character is not strictly smaller than the first:
[x| x <- mapM (const "ABCD") [1..2], head x < head (tail x) ]
(Based on #FrankSchmitt’s answer)
We have map (const x) [1..n] == replicate n x so we could change his answer to
[x| x <- sequence (replicate 2 "ABCD"), head x < head (tail x) ]
And while in original question, 2 was a parameter k, for this particular example would probably not want to replicate with 2 and write
[ [x1,x2] | x1 <- "ABCD", x2 <- "ABCD", x1 < x2 ]
instead.
With a parameter k things are a bit more tricky if you want to generate them without duplicates. I’d do it recursively:
f 0 _ = [[]]
f _ [] = []
f k as = [ x : xs | (x:as') <- tails as, xs <- f (k-1) as' ]
(This variant does not remove duplicates if there are already in the list as; if you worry about them, pass nub as to it)
This SO answer:
subsequences of length n from list performance
is the fastest solution to the problem that I've seen.
compositions :: Int -> [a] -> [[a]]
compositions k xs
| k > length xs = []
| k <= 0 = [[]]
| otherwise = csWithoutHead ++ csWithHead
where csWithoutHead = compositions k $ tail xs
csWithHead = [ head xs : ys | ys <- compositions (k - 1) $ tail xs ]

Concatenation of lists in Haskell

I want a function that takes two lists of any type and returns one (i.e. f:: [[a]] -> [[a]] -> [[a]]). Basically, too produce the 'concatenation' of the two input lists.
e.g.
> f [[1,2,3], [123]] [[4,5,6], [3,7]]
[[1,2,3,4,5,6], [1,2,3,3,7], [123,4,5,6], [123,3,7]]
I currently have got this far with it:
f _ [] = []
f [] _ = []
f (xs:xss) (ys:yss) = ((xs ++ ys) : [m | m <- f [xs] yss])
But this doesn't take into account xss and is wrong. Any suggestions?
It's a Cartesian product, so you can simply use one list comprehension to do everything.
Prelude> let xs = [[1,2,3], [123]]
Prelude> let ys = [[4,5,6], [3,7]]
Prelude> [x ++ y | x <- xs, y <- ys]
[[1,2,3,4,5,6],[1,2,3,3,7],[123,4,5,6],[123,3,7]]
import Control.Applicative
(++) <$> [[1,2,3], [123]] <*> [[4,5,6], [3,7]]
[[1,2,3,4,5,6],[1,2,3,3,7],[123,4,5,6],[123,3,7]]
f l1 l2 = [x ++ y | x <- l1, y <- l2]
In Alternative:
import Control.Applicative
f :: (Applicative f, Alternative g) => f (g a) -> f (g a) -> f (g a)
f = liftA2 (<|>)
f a b = map concat . sequence $ [a,b]
Scales up for combining any number of lists.

Resources