So I'm trying to triplize an element, i.e. making 2 other copies of the element.
So I've written this:
triplize :: [a] -> [a]
triplize [x] = concatMap (replicate 3) [x]
But I've been getting this error:
Non-exhaustive patterns in function triplize
I'm new to Haskell, so any pointers are appreciated!
When you write
triplize [x]
You are saying that the argument must match the pattern [x]. This pattern represents a list with a single value, which will be assigned to the name x. Note that the list will not be assigned to the name x, only the single value in that list. If you tried calling your function with the list [] or [1, 2], it would cause an error because you haven't told your function what to do with those inputs.
What you probably want is
triplize x = concatMap (replicate 3) x
Here your pattern is just x, which matches any list, from the empty list to an infinite list. Notice that the patterns in your function definition match the way you make the values themselves. In Haskell you can pattern match on constructors, and lists can be constructed with square brackets and commas, or they can be constructed using the : operator, so [1, 2, 3] == (1:2:3:[]). In fact, the : operator is how Haskell represents lists internally.
An example that uses more pattern matches:
sumSuccessive :: [Int] -> [Int]
sumSuccessive [] = [] -- Empty list
sumSuccessive [x] = [x] -- Singleton list (only one value)
sumSuccessive (x:y:rest) = x + y : sumSuccessive rest
-- Match a list with at least two elements `x` and `y`,
-- with the rest of the list assigned to the name `rest`
This example function would take the list [1, 2, 3, 4] and return the list [3, 7] ([1 + 2, 3 + 4]).
You can define triplize as:
triplize :: [a] -> [a]
triplize x = concatMap (replicate 3) x
But there's even no need to write x:
triplize :: [a] -> [a]
triplize = concatMap (replicate 3)
The original code will work only on lists with one element:
> triplize [1]
[1, 1, 1]
> triplize []
*** Exception: Non-exhaustive patterns in function triplize
> triplize [0, 1]
*** Exception: Non-exhaustive patterns in function triplize
[x] matches a list of exactly one element. If you want to match any list, just remove [ and ]:
triplize x = concatMap (replicate 3) x
This would turn ["a", "b", "c"] into ["a", "a", "a", "b", "b", "b", "c", "c", "c"].
On the other hand, if you want to take one element and return a list (containing 3 of that element), then your code should be
triplize :: a -> [a]
triplize x = replicate 3 x
Related
Reading the book Get Programming with Haskell, one of the questions was to find if a given element is in the first half of a list. This can be done as
isInFirstHalf x xs = elem x firstHalf
where firstHalf = take (length xs `div` 2) xs
However, the problem is that here length traverses the whole list. In an imperative language, one can shortcircut the loop early by keeping track of the element index and the current counter. E.g. if the list has a million elements, and there was a match on the third element, once you finish looping through the sixth element, you can immediately return true.
My question is if there's a way to implement something like this in Haskell.
Sure.
halfAsLong (x:_:xs) = x:halfAsLong xs
halfAsLong _ = []
isInFirstHalf x xs = elem x (zipWith const xs (halfAsLong xs))
Try it out:
> isInFirstHalf 3 (1:2:3:4:5:6:undefined)
True
Exercises for the reader:
Where did the element index and current counter of your proposed imperative solution go? (They are still in there, just hidden in a way I think is a bit subtle!)
This rounds down when dividing odd lengths in half, like length xs `div` 2 does. How would the code have to change to round up, like (length xs + 1) `div` 2 does?
Daniel Wagner posted a very nice answer that shows that you don't really need indices, after all.
Still, if you do want to use indices, a solution can be crafted as follows.
We enumerate all the list elements by pairing them with their indices. This is done by using zip [0..] xs (or zip [1..] xs if you want to start counting at 1).
We find whether your x is in the list, and find its index i if it's present. One could proceed by direct recursion, or use something like dropWhile ((/= x) . fst) ... and then test the result.
Once we know i, we need to check whether there are at least i elements after that. This can be solved by direct recursion, or by dropping i-1 elements and testing whether the result is a non empty list.
There are other alternatives, of course. We could for instance skip enumerating elements with zip [0..] and use recursion by keeping track of the current index: foo n x (y:ys) = ... foo (n+1) x ys ....
Here’s another way to think of the task. An element x appears in the first half of a list xs, excluding the midpoint, if there are strictly fewer elements before the first occurrence of the element than after it.
We can write break (== x) xs using the standard function break :: (a -> Bool) -> [a] -> ([a], [a]) to split xs into two parts: those appearing before x (or all of xs, if x is not found), and the remainder (including x, if it is found).
> break (== 0) []
([], [])
> break (== 0) [0, 1]
([], [0, 1])
> break (== 0) [1, 0]
([1], [0])
> break (== 0) [1, 2, 0, 3, 4]
([1, 2], [0, 3, 4])
> break (== 0) [1, 2, 3, 4]
([1, 2, 3, 4], [])
We then want to compare the lengths of these two parts without calculating the actual lengths strictly as Int. To do so, we can compute the shape of each part by ignoring all its elements, using shape = map (const ()), a.k.a. void :: (Functor f) => f a -> f () specialised to lists.
shape :: [a] -> [()]
shape = void
The Ord instance for lists sorts them lexicographically, and all values of type () are equal—okay, the only value of type ()—so a comparison of shapes [()] is a comparison of the lengths of the lists, which is also lazy enough for our purposes. (For maximal laziness, shape could be defined as genericLength on a lazy natural number type like data N = Z | S N with an appropriate Ord instance.)
> [] < repeat ()
True
> shape [5 .. 10] >= shape [1 .. 3]
True
> shape [1 .. 3] > shape [1 ..]
False
We can also “decrement” the shape of a list using drop 1, which we’ll use to skip counting the element itself if it was found. (Alternatively, we could “increment” the shape with (() :).)
Finally, putting these elements together leads to a fairly simple solution:
isInFirstHalf :: (Eq a) => a -> [a] -> Bool
isInFirstHalf x xs = shape before < shape (drop 1 after)
where
(before, after) = break (== x) xs
Notice that if the element was not found, after will be empty, so drop 1 will have no effect, but the shape of before can’t possibly be smaller than the empty shape [], so the comparison (<) will still correctly return False.
This question already has answers here:
Haskell: Is there an idiomatic way to insert every item in a list into its own list?
(6 answers)
Closed 5 years ago.
How can I turn a list into the nested list such as:
[p,q,q] -> [[p],[q],[q]]
I have tried this way:
return [2,5,6] // But the result is wrong -> [[2,5,6]] (correct would be [[2],[5],[6]] )
Implementation of return looks like this:
return x = [x]
You should apply it every element of the list, not to the list itself, which can be achieved using map:
map (\x -> [x]) [2, 5, 6]
or, equivalently
map (:[]) [2, 5, 6]
or, as you suggest, using return in place of \x -> [x]
map return [2, 5, 6]
Note that in the latter case, the type of the value returned will be (Monad m) => [m a], which is more general than [[a]].
nest [] = []
nest (x:xs) = [x]:nest xs
nest (x:xs) = [x]:nest xs
This splits the input up in to the first value of the array (x) and the rest of the array (xs) and then puts the first value in to an array and puts it at the start of an array where the next value is the next part of the array.
nest [] = []
This terminates the recursion when the list is empty.
A simple list comprehension also works here:
toNested :: [a] -> [[a]]
toNested xs = [[x] | x <- xs]
I'm very new to Haskell, and I decided to learn it some days ago, thanks to the haskell wikibook.
I'm reading at this moment the matching pattern for lists, but I can't understand the syntax for list.
Here's an example (from the wikibook) :
doubleList :: [Integer] -> [Integer]
doubleList [] = []
doubleList (n:ns) = (2 * n) : doubleList ns
I don't understand the part (n:ns). How should I read it ?
You can read it like this: (head:tail), so if you have [1, 2, 3] and you match it with (x:xs), then x will be bound to the first element in the list, 1, and xs will be bound to the rest of the list, in this case [2, 3].
(:) is an operator with type a->[a]->[a]. This means that it takes an item, and a list of those items, and returns another list of the same items. The output list is formed by prepending the input item to the input list.
Here is how you can use it
1:[2,3]
will return
[1,2,3]
Because the (:) appears on the left hand side of the definition, in your case, you are pattern matching, and the operator is being used to deconstruct the value, rather than build it.
For example, if we have
func (first:rest) = ....
and call it like this
func [1,2,3]
the following values would be assigned
first=1 --notice, this is type a
rest=[2,3] --notice, this is type [a]
Another tip that might help you understand is by looking at the definition of the list data type:
data [] a = [] | a : ([] a)
Note that Haskell makes special syntax rules just for the list type, normally [] is not a valid constructor. This definition is equivalent to
data List a = Empty | Cons a (List a)
Where
[] = Empty
(:) = Cons
You would pattern match on this as
doubleList :: List Int -> List Int
doubleList Empty = Empty
doubleList (Cons n ns) = Cons (2 * n) (doubleList ns)
If written using infix form:
doubleList (n `Cons` ns) = (2 * n) `Cons` doubleList ns
So now hopefully you can see the parallels between the two definitions. Haskell also provides the special syntax rule that
[1, 2, 3, 4] = 1:2:3:4:[]
Since the former is much easier to write and read. In fact, whenever you have a list literal like [1, 2, 3, 4] in your code, the compiler first converts it to 1:2:3:4:[] before converting your code into an executable.
I have a list, for example [1, 2, 3, 4, 5] and I have to duplicate each element of the list to form a list like [1, 1, 2, 2, 3, 4, 4, 5, 5].
As a hint, we're referred to the concat function which flattens a list of lists into a single list. But to try and understand how you would go about this in Haskell better, I'm trying to do it manually. Here is my attempt:
duplicate :: [a] -> [a]
duplicate [] = []
duplicate (x:xs) = x : (x:xs) duplicate xs
With the error message:
Couldn't match expected type `((a0 -> Bool) -> [a0] -> [a0])
-> [a] -> [a]'
with actual type `[a]'
The function `x : xs' is applied to two arguments,
but its type `[a]' has none
In the second argument of `(:)', namely `(x : xs) myTakeWhile xs'
In the expression: x : (x : xs) myTakeWhile xs
Failed, modules loaded: none.
My way of thinking is that you cons the head of the list to the whole list and then recursively call the function on the tail of this list. For example in pseudocode:
duplicate [1, 2, 3]
1 : [1, 2, 3] duplicate [2, 3]
2 : [2, 3] duplicate [3]
3: [3] duplicate []
return list [1, 1, 2, 2, 3, 3]
Is this an idiomatic way of approaching this problem and where am I going wrong in my attempt syntactically? I'm not looking for alternative, more efficient code solutions to this, I'm merely trying to get used to the functional way of approaching problems as opposed to imperative ways of looking at things.
Thanks!
The definition you're looking for is:
duplicate :: [a] -> [a]
duplicate [] = []
duplicate (x:xs) = x : x : duplicate xs
Since : is a right-associative operator, you can read that last alternative as
duplicate (x:xs) = x : (x : (duplicate xs))
or as
duplicate (x:xs) = (:) x ((:) x (duplicate xs))
Keeping in mind that [1, 2, 3] is just short for 1 : 2 : 3 : [], when duplicate is applied to [1, 2, 3], the second alternative is used because it matches the pattern x : xs (namely with x = 1 and xs = 2 : 3 : []). You want the result to begin twice with the head (which is the x : x : ... part of the definition), and continue with the duplicated tail (the ... : duplicate xs part).
I have a given list, e.g. [2, 3, 5, 587] and I want to have a complete list of the combination. So want something like [2, 2*3,2*5, 2*587, 3, 3*5, 3*587, 5, 5*587, 587]. Since I am on beginner level with Haskell I am curious how a list manipulation would look like.
Additionally I am curious if the computation of the base list might be expensive how would this influence the costs of the function? (If I would assume the list has limit values, i.e < 20)
Rem.: The order of the list could be done afterwards, but I have really no clue if this is cheaper within the function or afterwards.
The others have explained how to make pairs, so I concern myself here with getting the combinations.
If you want the combinations of all lengths, that's just the power set of your list, and can be computed the following way:
powerset :: [a] -> [[a]]
powerset (x:xs) = let xs' = powerset xs in xs' ++ map (x:) xs'
powerset [] = [[]]
-- powerset [1, 2] === [[],[2],[1],[1,2]]
-- you can take the products:
-- map product $ powerset [1, 2] == [1, 2, 1, 2]
There's an alternative powerset implementation in Haskell that's considered sort of a classic:
import Control.Monad
powerset = filterM (const [True, False])
You could look at the source of filterM to see how it works essentially the same way as the other powerset above.
On the other hand, if you'd like to have all the combinations of a certain size, you could do the following:
combsOf :: Int -> [a] -> [[a]]
combsOf n _ | n < 1 = [[]]
combsOf n (x:xs) = combsOf n xs ++ map (x:) (combsOf (n - 1) xs)
combsOf _ _ = []
-- combsOf 2 [1, 2, 3] === [[2,3],[1,3],[1,2]]
So it seems what you want is all pairs of products from the list:
ghci> :m +Data.List
ghci> [ a * b | a:bs <- tails [2, 3, 5, 587], b <- bs ]
[6,10,1174,15,1761,2935]
But you also want the inital numbers:
ghci> [ a * b | a:bs <- tails [2, 3, 5, 587], b <- 1:bs ]
[2,6,10,1174,3,15,1761,5,2935,587]
This uses a list comprehension, but this could also be done with regular list operations:
ghci> concatMap (\a:bs -> a : map (a*) bs) . init $ tails [2, 3, 5, 587]
[2,6,10,1174,3,15,1761,5,2935,587]
The latter is a little easier to explain:
Data.List.tails produces all the suffixes of a list:
ghci> tails [2, 3, 5, 587]
[[2,3,5,587],[3,5,587],[5,587],[587],[]]
Prelude.init drops the last element from a list. Here I use it to drop the empty suffix, since processing that causes an error in the next step.
ghci> init [[2,3,5,587],[3,5,587],[5,587],[587],[]]
[[2,3,5,587],[3,5,587],[5,587],[587]]
ghci> init $ tails [2, 3, 5, 587]
[[2,3,5,587],[3,5,587],[5,587],[587]]
Prelude.concatMap runs a function over each element of a list, and combines the results into a flattened list. So
ghci> concatMap (\a -> replicate a a) [1,2,3]
[1, 2, 2, 3, 3, 3]
\(a:bs) -> a : map (a*) bs does a couple things.
I pattern match on my argument, asserting that it matches an list with at least one element (which is why I dropped the empty list with init) and stuffs the initial element into a and the later elements into bs.
This produces a list that has the same first element as the argument a:, but
Multiplies each of the later elements by a (map (a*) bs).
You can get the suffixes of a list using Data.List.tails.
This gives you a list of lists, you can then do the inner multiplications you want on this list with a function like:
prodAll [] = []
prodAll (h:t) = h:(map (* h) $ t)
You can then map this function over each inner list and concatenate the results:
f :: Num a => [a] -> [a]
f = concat . map prodAll . tails