So I was strugging with this function doing calculation of length of each sublist. It takes a list containing sublists and return a new list with each element specifies the size of each sublist.
Something like:
*Main> count [[], ["this", "is"], ["a", "test", "!!!"]]
should return
[0,2,3]
Here is what I have so far, but it only prints the total size of every sublist of the entire list which is
[5]
Code:
count :: [[a]] -> [Int]
count [] = []
count (x:xs) = [1 + myLength (x:xs)]
Btw myLength is a trivial function I wrote to calculate the size.
There are Prelude defined length and map. So your count can be defined as simple as:
count = map length
Note that your input list is list of list, so you have to do this:
count :: [[a]] -> [Int]
count [] = []
count (x:xs) = (myLength x):(count xs)
You need to calculate the length using myLength function and for each element of the list and build it up using : function. xs will be the rest of the list, which you have to pass it to count again to compute it.
Eugene Sh offered the best (simplest) answer above: just use map length on your input.
But it sounds like this problem is homework, where the intent is to demonstrate basic understanding of recursion. So really we shouldn't be helping you :) But I will try to explain in a way that gives more than merely the answer.
With any recursive definition, you must first define your base cases. Since you are dealing with lists of lists, your simplest case is a list containing no sublists - its patterns looks like [].
You also have to define a recursive case (sometimes also called an inductive case), in which the right-hand side of the equation will contain a reference to the very function being defined.
So, your two necessary definitions for a sublists length function called len:
len (xs:xss) = length xs : len xss
len _ = []
Our first line defines the recursive case; notice its right-hand side contains a reference to the function we are defining (len, in this example). We use the popular Haskell conventions of xs for a list of arbitrary content type, and xss for a list of lists. The overall pattern, (xs:xss) matches any input with a list (xs) followed by any number of further lists (xss) - note, this could mean zero further lists! In that case, the pattern would concretely be xs:[].
For the second line, we did not bother to give an explicit pattern - we used the wildcard pattern _. This communicates to Haskell (and other programmers) the fact that we want [] to be returned for any input other than the one matched by the line above. Thus, when our recursion finally reaches the end of the list, it encounters a pattern like [] - a single list, not followed by any other lists. This is our base case, where we define the final output which ends the recursion.
Related
I'm a Haskell beginner following exercises from a book. The first question asked me to define a function that deletes the first occurrence of an integer from a list of integers.
E.g.
delete 5 [1,5,3,5,1]
outputs:
[1,3,5,1]
The second question asks me to create a function that uses the delete function I just defined, that takes as an argument a list of integers, and outputs a list of all the permutations as lists.
E.g.
perms [1,2,3]
outputs:
[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
I tried hard, gave up and googled the solution.
Here's what I found:
perms [] = [[]]
perms xs = [ i:j | i <- xs, j <- perms $ delete i xs ]
I looked around and found many other similar solutions, almost identical, just using different variable names and parentheses instead of the $ symbol, so I'm guessing this is a common problem with an idiomatic solution.
I'm just a little lost trying to understand exactly what this code is doing. I am seeking a step by step explanation through the recursion, to understand how this code is creating a list of permutations?
Like any recursive function that operates on lists, this one can be broken down into two cases:
1) What should the function do on an empty list?
2) If I know what the function does on a list of length n, can I use that to figure out what the function should do on a list of length n + 1.
Once you know those two things, you have a definition that will work on any list (at least one of finite length - such a procedure will of course never end for one of infinite length; that doesn't matter here as it doesn't make much sense to talk about permutations from an infinite list). [If you have any sort of mathematical background, you will recognise this as a simple statement of the law of mathematical induction.]
For the perms function, it is clear that there is only one way to permute the 0 elements of the empty list: another empty list. This gives [[]] for the base case, as in the first line of the example solution.
For the recursive/inductive step, let's say we have a list xs of length n (where n > 0), and suppose (as we are allowed to) that we already know how to compute all permutations of any list of length n - 1.
Each permutation must start with a particular element of the xs - let's call this element i, and think about how to get all the permutations of xs whose first element is i. It should be clear that these correspond precisely with all permutations of the list delete i xs (that is, xs with one i removed) - given a permutation j of the latter, the list i : j is a permutation of xs which begins with i, and conversely all such permutations of xs can be obtained in that way.
Note that this is exactly the list [ i:j | j <- perms $ delete i xs ]
(And note in passing that, since we've assumed i is in xs, delete i xs indeed has length n - 1, so by the inductive hypothesis we know how to compute this.)
i of course was chosen completely arbitrarily there - and all elements of xs will need to be accounted for as the first element of some permutations. So we simply put together all of the above, for all elements i in xs - which is exactly what the expression in the recursive step is:
[ i:j | i <- xs, j <- perms $ delete i xs ]
You might need to read some of the above slowly, a few times, before it makes sense - but it is fundamentally very elementary logic (and like most elementary logic, has a nasty habit of often looking more complicated than it actually is).
One by one take a single element i from xs
Delete i from xs and prepend i to j (every list element of the perms of xs less i) up until all is are depleted.
I'm just wondering, for recursion example:
squaresRec :: [Double] -> [Double]
squaresRec [] = []
squaresRec (x:xs) = x*x : squaresRec xs
Why on the recursive case, there is no bracket? Shouldn't it suppose to be like this:
squaresRec :: [Double] -> [Double]
squaresRec [] = []
squaresRec [x:xs] = x*x : squaresRec xs
I know this will not work. But just wondering the explanation behind it.
[] matches the empty list.
[1] matches a list containing exactly one element, and that must be a number equal to one. Note that [1] is actually syntactic sugar for (1:[]), i.e. what this really matches is: a list beginning with the number 1, followed by a list that is empty... which is just a complicated way of saying “a list containing the single element 1”.
(x:xs) matches a list that begins with x, followed by xs (and that may contain any number of elements, possibly zero). I.e. this pattern matches any list with at least one element.
[x:xs] matches again a list which contains exactly one element, and that element should match the pattern (x:xs). (Which doesn't make sense even type-wise, because your lists contain Double-numbers, not lists.)
I had the same problem because I'm coming from Erlang.
The thing to understand is that the [head|tail] pattern we have in Erlang is actually translated by the cons function in Haskell, which is the : operator. The parenthesis are just here to isolate the function parameters, like (3+4) would do.
I know it's tempting to ask "why though???" and that it visually makes more sense, but : is how we build (and separate when pattern-matching) the head and the tail of a linked list.
I would like to know how haskell evauates the following expression.
span (`elem` ['A'..'Z']) "BOBsidneyMORGANeddy"
The result is
("BOB","sidneyMORGANeddy")
Could anyone explain me the evaluation process? Because I can't tell why it is split as above.
span will partition the list into two using a predicate in such a way that the first part is the longest prefix for which a given predicate holds true, and the second part is the remainder of the list. In other words, the first part is obtained like with takeWhile, and the second part is obtained like with dropWhile for the same predicate.
Now let's look at the predicate. elem :: a->[a]->Bool tells whether the given element is found in the given list. The neat trick is that any function of two or more arguments can be used in infix notation:
x `elem` xs
is the same as elem x xs. Therefore,
`elem` xs
is treated just like sections of infix functions. It is the same as \x -> elem x xs.
You can see now that span is given a predicate testing whether the elements of the list to split can be found in the list ['A'..'Z']. So it will split the list into two: it finds the first element for which the predicate doesn't hold, and that's the split point. This is how the second partition starts with the first lowercase letter.
So I wanted to do a simple string reverse function in Haskell
swapReverse :: String => String
swapReverse [x] = [x]
swapReverse [x,y] = [y,x]
swapReverse (x:xs:l) = -- pattern match fails here
let last = [l]
middle = xs
first = [x]
in last ++ swapReverse middle ++ first
So is there a way to define a pattern structure in haskell that has first and last element, and all the elements in the middle ?
No, you cannot. Why? Because pattern matches match values and their subparts, but the "middle" of a list isn't a subpart of the list. The list [1, 2, 3, 4] is 1:(2:(3:(4:[]))), in terms of its structure. So you want to match first to 1 and last to 4, which are both subparts of the list, and thus not disqualified. But the middle that you want would be 2:(3:[]), which is not a subpart of the list, and thus, cannot be a match.
Note that we can't write a pattern to match the first and the last elements of a list simultaneously, either. A pattern has a depth that's fixed at compilation time.
Pattern matching works on constructors, : is the only list constructor so you can not match on the middle of the list. You need to construct the new list backwards (obviously :) ) which can be done by taking the head and appending that to the reverse of the rest of the list.
Try this code:
last1 (x:xs:l) = (x,xs,l)
l doesn't get you the last element in a list, it get's you the rest of the list besides the first two variables, which are assigned the first two elements in a list.
When you write a pattern match for a list, the first variable is assigned the first element, and so on, until the program get's to the last variable, where everything that is left is assigned to it. There is nothing special about adding an s after an x, a variable named y would do the same thing.
If you want to get the last element of a list, you need to create a pattern similar to (x:xs), and use recursion on xs and apply that pattern until you get down to one list element, which is the last element. However, I would recommend reading Adam Bergmark's answer for a better way to reverse a list that does not involve finding the first and last elements of a list.
A working version:
swapReverse :: String -> String
swapReverse (x:xs) = [last xs] ++ swapReverse (init xs) ++ [x]
swapReverse xs = xs
Note that this implementation is performance-wise a disaster. Implementations using a fold and/or accumulators are much more efficient.
So, I'm new here, and I would like to ask 2 questions about some code:
Duplicate each element in list by n times. For example, duplicate [1,2,3] should give [1,2,2,3,3,3]
duplicate1 xs = x*x ++ duplicate1 xs
What is wrong in here?
Take positive numbers from list and find the minimum positive subtraction. For example, [-2,-1,0,1,3] should give 1 because (1-0) is the lowest difference above 0.
For your first part, there are a few issues: you forgot the pattern in the first argument, you are trying to square the first element rather than replicate it, and there is no second case to end your recursion (it will crash). To help, here is a type signature:
replicate :: Int -> a -> [a]
For your second part, if it has been covered in your course, you could try a list comprehension to get all differences of the numbers, and then you can apply the minimum function. If you don't know list comprehensions, you can do something similar with concatMap.
Don't forget that you can check functions on http://www.haskell.org/hoogle/ (Hoogle) or similar search engines.
Tell me if you need a more thorough answer.
To your first question:
Use pattern matching. You can write something like duplicate (x:xs). This will deconstruct the first cell of the parameter list. If the list is empty, the next pattern is tried:
duplicate (x:xs) = ... -- list is not empty
duplicate [] = ... -- list is empty
the function replicate n x creates a list, that contains n items x. For instance replicate 3 'a' yields `['a','a','a'].
Use recursion. To understand, how recursion works, it is important to understand the concept of recursion first ;)
1)
dupe :: [Int] -> [Int]
dupe l = concat [replicate i i | i<-l]
Theres a few problems with yours, one being that you are squaring each term, not creating a new list. In addition, your pattern matching is off and you would create am infinite recursion. Note how you recurse on the exact same list as was input. I think you mean something along the lines of duplicate1 (x:xs) = (replicate x x) ++ duplicate1 xs and that would be fine, so long as you write a proper base case as well.
2)
This is pretty straight forward from your problem description, but probably not too efficient. First filters out negatives, thewn checks out all subtractions with non-negative results. Answer is the minumum of these
p2 l = let l2 = filter (\x -> x >= 0) l
in minimum [i-j | i<-l2, j<-l2, i >= j]
Problem here is that it will allow a number to be checkeed against itself, whichwiull lend to answers of always zero. Any ideas? I'd like to leave it to you, commenter has a point abou t spoon-feeding.
1) You can use the fact that list is a monad:
dup = (=<<) (\x -> replicate x x)
Or in do-notation:
dup xs = do x <- xs; replicate x x; return x
2) For getting only the positive numbers from a list, you can use filter:
filter (>= 0) [1,-1,0,-5,3]
-- [1,0,3]
To get all possible "pairings" you can use either monads or applicative functors:
import Control.Applicative
(,) <$> [1,2,3] <*> [1,2,3]
[(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)]
Of course instead of creating pairs you can generate directly differences when replacing (,) by (-). Now you need to filter again, discarding all zero or negative differences. Then you only need to find the minimum of the list, but I think you can guess the name of that function.
Here, this should do the trick:
dup [] = []
dup (x:xs) = (replicate x x) ++ (dup xs)
We define dup recursively: for empty list it is just an empty list, for a non empty list, it is a list in which the first x elements are equal to x (the head of the initial list), and the rest is the list generated by recursively applying the dup function. It is easy to prove the correctness of this solution by induction (do it as an exercise).
Now, lets analyze your initial solution:
duplicate1 xs = x*x ++ duplicate1 xs
The first mistake: you did not define the list pattern properly. According to your definition, the function has just one argument - xs. To achieve the desired effect, you should use the correct pattern for matching the list's head and tail (x:xs, see my previous example). Read up on pattern matching.
But that's not all. Second mistake: x*x is actually x squared, not a list of two values. Which brings us to the third mistake: ++ expects both of its operands to be lists of values of the same type. While in your code, you're trying to apply ++ to two values of types Int and [Int].
As for the second task, the solution has already been given.
HTH