Haskell - make a 2D list out of a 1D list - haskell

I have to make a 2D list [[Int]]. out of a 1D list [Int] in Haskell.
The function should take to args "r" Int indicates the count of rows and a 1D list, which should be sliced into rows with the length of "r".
If length of the list is longer than r*r then the rest of the list should be dropped.
Howerver
If length of the list is shorter than r*r then the missing elements should be inserted in the list as 0.
Example 1:
Input:
r = 2
list = [1,2,3,4,5,6]
Output: [[1,2], [3,4]]
Example 2:
Input:
r = 3
list = [1,2,3,4,5,6]
Output: [[1,2,3], [4,5,6], [0,0,0]]
So my approach is over thre functions as follow:
zeroList :: Int -> [Int] -> [Int]
zeroList r myList = (take (r*r-(length myList)) (0 : zeroList r myList))
processList :: Int -> [Int] -> [[Int]]
processList r myList = (if (length myList < r*r)
then (myList:(zeroList r myList))
else if (length (myList > r*r))
then (reverse (drop r (reverse myList)))
else
myList)
make2DList :: Int -> [Int] -> [[Int]]
make2DList r myList = (if myList == []
then make2DList
else ( ( take r (processList r myList) ):( make2DList r ( drop r (processList r myList) ) )))
The zeroList function works properly but the other two functions don't work. I some compiling error messages:
D:\haskell\task1.hs:6:63:
Couldn't match expected type `[Int]' with actual type `Int'
Expected type: [[Int]]
Actual type: [Int]
In the return type of a call of `zeroList'
In the second argument of `(:)', namely `(zeroList r myList)'
D:\haskell\task1.hs:14:54:
Couldn't match expected type `[[Int]]'
with actual type `Int -> [Int] -> [[Int]]'
In the expression: make2DList
In the expression:
(if myList == [] then
make2DList
else
((take r myList) : (make2DList r (drop r myList))))
In an equation for `make2DList':
make2DList r myList
= (if myList == [] then
make2DList
else
((take r myList) : (make2DList r (drop r myList))))
Failed, modules loaded: none.
Prelude>
I can't comprehend, why it doesn't work although zeroList r myList. returns an ordinary list.
Could anyone help me please?

I have to admit that I don’t comprehend how you are trying to do it. All this if then else is quite unHaskellish. :-) Also, due to Haskell’s lazy evaluation and infinite lists, it is unnecessary to compute the exact number of needed zeroes etc. beforehand.
A rough draft how it could be done instead:
make2DList r l = take r . chunks r $ l ++ zeroes
where
zeroes = [0,0..]
chunks r xs = take r xs : chunks r (drop r xs)
Explanation:
Extend the list by an infinite number of zeroes so we don’t have to worry about padding anymore.
Make a chunks function that splits any list into chunks of the given length.
Apply chunks to the padded list.
Take as many rows as we need.

I can explain both of the compilation errors, and I have a question for you. I'll take the errors in reverse order.
Error at 14:54
First I'll explain how arguments are applied to functions in Haskell.
The function make2DList has type Int -> [Int] -> [[Int]], which is equivalent to Int -> ( [Int] -> [[Int]] ). This means that, if given one argument r (which must be of type Int) it returns a function of type [Int] -> [[Int]]. This returned function, if given an argument myList (which must be of type [Int]) returns a list of type [[Int]].
This means that the code make2DList r myList is equivalent to (make2DList r) myList. In any case, it must return a value of type [[Int]], that is, a list of lists of Ints.
But you have said that, in the event that myList is empty, it should return just make2DList. Unfortunately make2DList is a function of type Int -> [Int] -> [[Int]] and not a list of lists of type [[Int]], hence the compiler error message
Couldn't match expected type `[[Int]]'
with actual type `Int -> [Int] -> [[Int]]'
The fix is to supply some arguments to this call to make2DList. But do not supply an empty list as the second argument, or you will create an infinite loop. Probably what you actually want to do is to return an empty list of lists, written the same way as an empty list of anything: []
Edit: I should perhaps also explain how if ... then ... else works in Haskell. This is not at all like the if/then/else in imperative languages, and is actually just like the ternary operator. That is,
if a then b else c
in Haskell is, as far as I can tell, exactly the same as
a ? b : c
in another language.
Thus, in order for the whole expression (if a then b else c) to be of the right type, both b and c must be of the right type (and a must be boolean, of course). In your case, the whole if/then/else expression should be of type [[Int]] but your b is the expression make2DList (with no arguments), which is of course a function and not a list of lists as it should be.
Error at 6:63
The type of : is given by (:) :: a -> [a] -> [a]. This means that if whatever is on the left of the : has type a (for some a), then whatever is on the right should have type [a].
That is to say, whatever appears to the left of : will become the first element in the resulting list, and whatever is on the right of : will become the rest of the list, which means that the type of the rest of the list must be a list of the type of whatever the first element is.
Your first element is myList, which has type [Int], and what you're trying to use for the rest of the list is (zeroList r myList), which also has type [Int] and is thus only good as a single element.
Possible fixes (which would compile, but may or may not be correct) could include:
enclosing zeroList r myList in square brackets, thus:
myList:[zeroList r myList]
which would always create a list of two elements, each of which would be a list of Ints
concatenating the two lists, thus:
myList ++ (zeroList r myList)
but this would produce the wrong return type, so you'd have to put the result in another list. The following would compile, but is almost certainly not what you want:
[myList ++ (zeroList r myList)]
That r probably wants to be something like r - (length myList) or something too.
Question
I'm having trouble guessing how your functions are supposed to work. What are each of the two functions processList and make2DList supposed to do? I see that they both have the same type, so what is the difference?

import Data.List (replicate)
takeElse :: Int -> a -> [a] -> [a]
takeElse 0 _ _ = []
takeElse n alt [] = replicate n alt
takeElse n alt (x : xs) = x : takeElse (n - 1) alt xs
exotic :: Int -> a -> [a] -> [[a]]
exotic dum alt lst = exot dim lst
where
exot 0 _ = []
exot n xs = takeElse dim alt xs : exot (n - 1) (drop dim xs)
such that
exotic 3 0 [1,2,3,4] == [[1,2,3],[4,0,0],[0,0,0]]
exotic 1 ' ' "Hello" == ["H"]
exotic 4 ' ' "Hello" == ["Hell","o "," "," "]
takeElse 10 ' ' "Hello" == "Hello "

Related

Haskell shift list

I want to shift a list by n elements to the left. Why do I get an error if I want to change the order from (x:xs) to (xs:x)?
shift n list#(x:xs)
| n == 0 = list
| otherwise = shift (n-1) (xs:x) -- (xs:x) error
Occurs check: cannot construct the infinite type: a ~ [a]
I don't know how to interpret this error. Maybe someone of you can help me.
Thank you very much.
EDIT: As it was already mentioned, the correct term to use is rotate and not shift
Why do I get an error if I want to change the order from (x:xs) to (xs:x)?
Because the types do not match. The type of (:) is (:) :: a -> [a] -> [a]. It thus expects an element x (type a) and a list with the rest of the elements (type [a]). You can not just use (:) in the opposite way.
You can use the (++) :: [a] -> [a] -> [a] to concatenate two lists together. We can thus rotate to the left by dropping n elements from the list and concatenating this with the first n elements of the list to this.
rotateL :: Int -> [a] -> [a]
rotateL 0 list = list
rotateL n list | n < 0 = error "Negative index"
| otherwise = drop n list ++ take n list
or we can, like #YannVernier says, use splitAt :: Int -> [a] -> ([a], [a]):
rotateL :: Int -> [a] -> [a]
rotateL 0 list = list
rotateL n list | n < 0 = error "Negative index"
| otherwise = lb ++ la
where (la, lb) = splitAt n list
or without mentioning the list parameter:
rotateL :: Int -> [a] -> [a]
rotateL 0 = id
rotateL n | n < 0 = error "Negative index"
| otherwise= uncurry (flip (++)) . splitAt n
Note: based on how your attempt, I think you actually want to rotate the list to the left, not shift it, since that would mean that you simply drop the first n elements, and fill it perhaps with some extra value.
Note: in case n is larger than the length of the list, then the rotateL will act as an identity function. That might not be the desired behavior. I leave it as an exercise to fix this edge-case.
It's not the names that define the types, but the positions in a function call, or type declarations. If we check the type of :, we see that the second argument is a list:
Prelude> :t (:)
(:) :: a -> [a] -> [a]
So pattern matching on this constructor will always give you the head and tail, not the init and last. Thus, using both x:xs and xs:x, you've declared that a and [a] are the same type, and the compiler balks. You could perform the append using e.g. xs ++ [x].
Data.Sequence has a type that does support both head and last patterns in the operators :<| and |>:.
In general, (singly linked) lists only make the head element efficiently accessible; operations like appending or even checking lengths are costly. When all you need is a stream or stack, they're great, but a long distance reordering operation like the rotation is better handled by a rope or circular buffer type. Either is available in Haskell, in e.g. container's Seq or ring-buffer's RingBuffer. Data.ByteString.Lazy and Data.Text.Lazy are also rope types.

How to implement the function find with the filter function?

I'm making some exercise to practice my Haskell skills. My task is to implement the Haskell function find by myself with the filter function.
I already implemented the find function without the filter function (see codeblock below) but now my problem is to implement it with filter function.
-- This is the `find` function without `filter` and it's working for me.
find1 e (x:xs)= if e x then x
else find1 e xs
-- This is the find function with the filter function
find2 e xs = filter e xs
The result of find1 is right
*Main> find1(>4)[1..10]
Output : [5].
But my actual task to write the function with filter gives me the
*Main> find2(>4)[1..10]
Output : [5,6,7,8,9,10].
My wanted result for find2 is the result of find1.
To "cut a list" to only have one, head element in it, use take 1:
> take 1 [1..]
[1]
> take 1 []
[]
> take 1 $ find2 (> 4) [1..10]
[5]
> take 1 $ find2 (> 14) [1..10]
[]
If you need to implement your own take 1 function, just write down its equations according to every possible input case:
take1 [] = []
take1 (x:xs) = [x]
Or with filter,
findWithFilter p xs = take1 $ filter p xs
Your find1 definition doesn't correspond to the output you show. Rather, the following definition would:
find1 e (x:xs) = if e x then [x] -- you had `x`
else find1 e xs
find1 _ [] = [] -- the missing clause
It is customary to call your predicate p, not e, as a mnemonic device. It is highly advisable to add type signatures to all your top-level definitions.
If you have difficulty in writing it yourself you can start without the signature, then ask GHCi which type did it infer, than use that signature if it indeed expresses your intent -- otherwise it means you've coded something different:
> :t find1
find1 :: (t -> Bool) -> [t] -> [t]
This seems alright as a first attempt.
Except, you actually intended that there would never be more than 1 element in the output list: it's either [] or [x] for some x, never more than one.
The list [] type is too permissive here, so it is not a perfect fit.
Such a type does exist though. It is called Maybe: values of type Maybe t can be either Nothing or Just x for some x :: t (read: x has type t):
import Data.Maybe (listToMaybe)
find22 p xs = listToMaybe $ filter p xs
We didn't even have to take 1 here: the function listToMaybe :: [a] -> Maybe a (read: has a type of function with input in [a] and output in Maybe a) already takes at most one element from its input list, as the result type doesn't allow for more than one element -- it simply has no more room in it. Thus it expresses our intent correctly: at most one element is produced, if any:
> find22 (> 4) [1..10]
Just 5
> find22 (> 14) [1..10]
Nothing
Do add full signature above its definition, when you're sure it is what you need:
find22 :: (a -> Bool) -> [a] -> Maybe a
Next, implement listToMaybe yourself. To do this, just follow the types, and write equations enumerating the cases of possible input, producing an appropriate value of the output type in each case, just as we did with take1 above.

Pattern match(es) are non-exhaustive

I'm trying to create a function that eliminates multiples of a given Integer from a list of Integers, in the form multiples x [y], where x is the given Integer, and y is the list.
Here's what I have:
multiples :: Integer -> [Integer] -> [Integer]
multiples a [] = []
multiples a [b] = filter (\l -> l `mod` a /= 0) [b]
multiples will fail when called, saying "Non-exhaustive patterns in function multiples". So I used ghci -Wall with my file to see what patterns were missing, and it returns this:
multiples.hs:2:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for `multiples': Patterns not matched: _ (_:_:_)
multiples.hs:2:11: warning: [-Wunused-matches]
Defined but not used: `a'
I get the feeling I'm missing something really simple with line 2, but I'm a bit stuck. What am I doing wrong?
Welcome to Stack Overflow! There are a couple of things to fix in your function, but I'll start with the one you seem the most confused about: here [b] is a pattern matching a one-element list, naming its single item b. ([b, c] would be a pattern matching a two-element list, etc.) It's not a pattern matching an arbitrarily long list of bs. GHC is telling you off because you haven't accounted for the case where the function has been given a two-or-more-element list.
If you want to match an arbitrary list of bs, omit the square brackets. Additionally, the first line of your function is not necessary because the second line already deals with that case.
multiples :: Integer -> [Integer] -> [Integer]
multiples a bs = filter (\b -> b `mod` a /= 0) bs
Or, using a list comprehension,
multiples :: Integer -> [Integer] -> [Integer]
multiples a bs = [b | b <- bs, b `mod` a /= 0]
Two more things: I'd name this function withoutMultiples because it filters out multiples of a, and because Haskell functions are curried by default you can omit the bs in the filter version.
withoutMultiples :: Integer -> [Integer] -> [Integer]
withoutMultiples a = filter (\b -> b `mod` a /= 0)
Your pattern
multiples a [b]
expects an Integer (bound to name "a") and list of Integer containing one element (bound to name "b"). Remove square brackets (which will change type of "b" to [Integer]) in this pattern and it should be working. Also you can curry this function to form
multiples a = filter (\l -> l `mod` a /= 0)
and omit first pattern as it should be covered by filter function.

Compute Most Frequent Occurance of Numbers of A Sorted List in Haskell

The question is to compute the mode (the value that occurs most frequently) of a sorted list of integers.
[1,1,1,1,2,2,3,3] -> 1
[2,2,3,3,3,3,4,4,8,8,8,8] -> 3 or 8
[3,3,3,3,4,4,5,5,6,6] -> 3
Just use the Prelude library.
Are the functions filter, map, foldr in Prelude library?
Starting from the beginning.
You want to make a pass through a sequence and get the maximum frequency of an integer.
This sounds like a job for fold, as fold goes through a sequence aggregating a value along the way before giving you a final result.
foldl :: (a -> b -> a) -> a -> [b] -> a
The type of foldl is shown above. We can fill in some of that already (I find that helps me work out what types I need)
foldl :: (a -> Int -> a) -> a -> [Int] -> a
We need to fold something through that to get the value. We have to keep track of the current run and the current count
data BestRun = BestRun {
currentNum :: Int,
occurrences :: Int,
bestNum :: Int,
bestOccurrences :: Int
}
So now we can fill in a bit more:
foldl :: (BestRun -> Int -> BestRun) -> BestRun -> [Int] -> BestRun
So we want a function that does the aggregation
f :: BestRun -> Int -> BestRun
f (BestRun current occ best bestOcc) x
| x == current = (BestRun current (occ + 1) best bestOcc) -- continuing current sequence
| occ > bestOcc = (BestRun x 1 current occ) -- a new best sequence
| otherwise = (BestRun x 1 best bestOcc) -- new sequence
So now we can write the function using foldl as
bestRun :: [Int] -> Int
bestRun xs = bestNum (foldl f (BestRun 0 0 0 0) xs)
Are the functions filter, map, foldr in Prelude library?
Stop...Hoogle time!
Did you know Hoogle tells you which module a function is from? Hoolging map results in this information on the search page:
map :: (a -> b) -> [a] -> [b]
base Prelude, base Data.List
This means map is defined both in Prelude and in Data.List. You can hoogle the other functions and likewise see that they are indeed in Prelude.
You can also look at Haskell 2010 > Standard Prelude or the Prelude hackage docs.
So we are allowed to map, filter, and foldr, as well as anything else in Prelude. That's good. Let's start with Landei's idea, to turn the list into a list of lists.
groupSorted :: [a] -> [[a]]
groupSorted = undefined
-- groupSorted [1,1,2,2,3,3] ==> [[1,1],[2,2],[3,3]]
How are we supposed to implement groupSorted? Well, I dunno. Let's think about that later. Pretend that we've implemented it. How would we use it to get the correct solution? I'm assuming it is OK to choose just one correct solution, in the event that there is more than one (as in your second example).
mode :: [a] -> a
mode xs = doSomething (groupSorted xs)
where doSomething :: [[a]] -> a
doSomething = undefined
-- doSomething [[1],[2],[3,3]] ==> 3
-- mode [1,2,3,3] ==> 3
We need to do something after we use groupSorted on the list. But what? Well...we should find the longest list in the list of lists. Right? That would tell us which element appears the most in the original list. Then, once we find the longest sublist, we want to return the element inside it.
chooseLongest :: [[a]] -> a
chooseLongest xs = head $ chooseBy (\ys -> length ys) xs
where chooseBy :: ([a] -> b) -> [[a]] -> a
chooseBy f zs = undefined
-- chooseBy length [[1],[2],[3,3]] ==> [3,3]
-- chooseLongest [[1],[2],[3,3]] ==> 3
chooseLongest is the doSomething from before. The idea is that we want to choose the best list in the list of lists xs, and then take one of its elements (its head does just fine). I defined this by creating a more general function, chooseBy, which uses a function (in this case, we use the length function) to determine which choice is best.
Now we're at the "hard" part. Folds. chooseBy and groupSorted are both folds. I'll step you through groupSorted, and leave chooseBy up to you.
How to write your own folds
We know groupSorted is a fold, because it consumes the entire list, and produces something entirely new.
groupSorted :: [Int] -> [[Int]]
groupSorted xs = foldr step start xs
where step :: Int -> [[Int]] -> [[Int]]
step = undefined
start :: [[Int]]
start = undefined
We need to choose an initial value, start, and a stepping function step. We know their types because the type of foldr is (a -> b -> b) -> b -> [a] -> b, and in this case, a is Int (because xs is [Int], which lines up with [a]), and the b we want to end up with is [[Int]].
Now remember, the stepping function will inspect the elements of the list, one by one, and use step to fuse them into an accumulator. I will call the currently inspected element v, and the accumulator acc.
step v acc = undefined
Remember, in theory, foldr works its way from right to left. So suppose we have the list [1,2,3,3]. Let's step through the algorithm, starting with the rightmost 3 and working our way left.
step 3 start = [[3]]
Whatever start is, when we combine it with 3 it should end up as [[3]]. We know this because if the original input list to groupSorted were simply [3], then we would want [[3]] as a result. However, it isn't just [3]. Let's pretend now that it's just [3,3]. [[3]] is the new accumulator, and the result we would want is [[3,3]].
step 3 [[3]] = [[3,3]]
What should we do with these inputs? Well, we should tack the 3 onto that inner list. But what about the next step?
step 2 [[3,3]] = [[2],[3,3]]
In this case, we should create a new list with 2 in it.
step 1 [[2],[3,3]] = [[1],[2],[3,3]]
Just like last time, in this case we should create a new list with 1 inside of it.
At this point we have traversed the entire input list, and have our final result. So how do we define step? There appear to be two cases, depending on a comparison between v and acc.
step v acc#((x:xs):xss) | v == x = (v:x:xs) : xss
| otherwise = [v] : acc
In one case, v is the same as the head of the first sublist in acc. In that case we prepend v to that same sublist. But if such is not the case, then we put v in its own list and prepend that to acc. So what should start be? Well, it needs special treatment; let's just use [] and add a special pattern match for it.
step elem [] = [[elem]]
start = []
And there you have it. All you have to do to write your on fold is determine what start and step are, and you're done. With some cleanup and eta reduction:
groupSorted = foldr step []
where step v [] = [[v]]
step v acc#((x:xs):xss)
| v == x = (v:x:xs) : xss
| otherwise = [v] : acc
This may not be the most efficient solution, but it works, and if you later need to optimize, you at least have an idea of how this function works.
I don't want to spoil all the fun, but a group function would be helpful. Unfortunately it is defined in Data.List, so you need to write your own. One possible way would be:
-- corrected version, see comments
grp [] = []
grp (x:xs) = let a = takeWhile (==x) xs
b = dropWhile (==x) xs
in (x : a) : grp b
E.g. grp [1,1,2,2,3,3,3] gives [[1,1],[2,2],[3,3,3]]. I think from there you can find the solution yourself.
I'd try the following:
mostFrequent = snd . foldl1 max . map mark . group
where
mark (a:as) = (1 + length as, a)
mark [] = error "cannot happen" -- because made by group
Note that it works for any finite list that contains orderable elements, not just integers.

The questions regarding my first haskell program

The program return all possible combinations of '0' and '1' length N.
addToElement :: String -> String -> String
addToElement element symbol = element ++ symbol
addOneToElement :: String -> String
addOneToElement element = addToElement element "1"
addZeroToElement :: String -> String
addZeroToElement element = addToElement element "0"
processListOnce :: [String] -> [String]
processListOnce lst = do
let s1 = map addOneToElement lst
let s2 = map addZeroToElement lst
s1 ++ s2
processList :: [String] -> Integer -> [String]
processList lst 1 = processListOnce lst
processList lst n = do
let tmp = processListOnce(lst)
processList tmp (n - 1)
{-
processList2 :: [String] -> Integer -> [String]
processList2 lst n = iterate (map processListOnce) lst !! n
-}
main = do
let s = processList ["0", "1"] 2
let ss = show s
putStrLn ss
It is my first Haskell program so I will be thankful if you help me:
First of all pls refactore my code Haskell-way. I already know one magic refactring:
Control.Monad.replicateM n [0,1]
but this solution is not good for studying purposes :)
Why I can not use ProcessList2 instead ProcessList and get error:
all_possible_combinations.hs:44:51:
Couldn't match expected type `[Char]' against inferred type `Char'
Expected type: [String]]
Inferred type: [String]
In the second argument of `iterate', namely `lst'
In the first argument of `(!!)', namely
`iterate (map processListOnce) lst'
Is there any way to skip (not use) the 'tmp' variable in the processList? I have tried, but got the error:
processList :: [String] -> Integer -> [String]
processList lst 1 = processListOnce lst
processList lst n = processList processListOnce(lst) (n - 1)
all_possible_combinations.hs:39:32:
Couldn't match expected type `[String]'
against inferred type `[String] -> [String]'
In the first argument of `processList', namely `processListOnce'
In the expression: processList processListOnce (lst) (n — 1)
In the definition of `processList':
processList lst n = processList processListOnce (lst) (n — 1)
Thanks in advance.
First of all pls refactore my code Haskell-way. I already know one magic refactring:
Control.Monad.replicateM n [0,1]
but this solution is not good for studying purposes :)
Actually, while I certainly wouldn't expect someone new to Haskell to come up with such a solution, I think that understanding this version would be very good for studying purposes.
The regular replicate function is pretty simple: It creates a list of the same element repeated some number of times. This is also the first step of what replicateM does:
> replicate 2 ["0", "1"]
[["0", "1"], ["0", "1"]]
The second step of what replicateM does is "sequence" the list according to the Monad of the elements, turning something a list of monadic values [m a] into a monadic list of values m [a]. What this does is "combine" the structure of each monadic value in some sense, where the specific meaning of "combine" depends on the specific monad.
As a Monad, lists represent something like trying multiple possibilities. So when we "sequence" the values, that means that at each step, every possibility is tried separately, and all possible results are collected.
So, ["0", "1"] is a monadic value representing trying two different possibilities. [["0", "1"], ["0", "1"]] is a list of that monadic value repeated twice. To sequence that list, we take each possibility from the first element of the list, use it as the head of the result list, then continue until reaching the end. Because each group of possibilities is the same, the final result is all the possible combinations of each possible item:
> replicateM 2 ["0", "1"]
[["0","0"],["0","1"],["1","0"],["1","1"]]
About making it Haskelly, here is a solution that is not pure magic (as the replicateM may be)
onesAndZeroes 0 = [[]]
onesAndZeroes n = [x:xs | x <- [0,1], xs <- onesAndZeroes (n-1)]
Since you are new to haskell, if you don't understand it, it might help to read about list comprehensions.
Is there any way to skip (not use) the 'tmp' variable in the processList? I have tried, but got the error:
This definition has used the wrong precedence. You should write
processList lst n = processList (processListOnce lst) (n - 1)
-- # ^ ^
Why I can not use ProcessList2 instead ProcessList and get error:
processListOnce is already a [String] -> [String] function. If you use map processListOnce it will become a [[String]] -> [[String]] function. Thus, remove the map.
processList2 lst n = iterate processListOnce lst !! n
Another solution:
onesAndZeroes n = combo n ["0", "1"]
where combo 1 cs = cs
combo n cs = combo (n-1) (f cs)
f = concatMap (\x -> ['0':x, '1':x])
Like others I think replicateM would be my first choice, but if I was to avoid that this would be my solution. Perhaps less clear/concise than the list comprehension solution, but I find tail call recursion quite elegant.

Resources