Haskell - span elem: evaluation - haskell

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.

Related

Distinguishing parentheses from brackets

In Haskell, I know that there are tuples (x1,x2,x3) and also lists [x1,x2,x3] and that tuples are not homogeneous and have a fixed length.
On the other hand, lists can be rewritten for example in the form x1:x2:x3:[], which I guess is a function a ->[a]->[a], which makes some sense to me, but in the following code:
head' :: [a] -> a
head' [] = error
head' (x:_) = x
it is unclear to me why we use parentheses, which is to my understanding tuple notation. It looks more like we should have something like an uncurry function on the colon operator, and take the first input, or something like that.
How are the parentheses behaving here, and why can we not use brackets in some way or another?
Parentheses denote tuples when they contain commas. Parentheses without commas are used for grouping, e.g. to distinguish between x - (y - z) and (x - y) - z or, in this case, between head' (x:_) = x and (head' x) : _ = x. In other words, all that the parentheses do here is to denote that : is being applied to x and _ rather than head' x and _.
If you used [] here, that would be a list pattern. Generally the pattern [p] matches if the given value is a list with one element and that element matches the pattern p. So [x:_] matches a list that contains one element and that element is itself a list matching the pattern x:_. Since that's not what you want, you need to use the version without the list pattern.
The parentheses in head' (x:_) are just being used for grouping; you can tell no tuples are involved because there are no commas inside. Without the parentheses, head' x:_ would be parsed as (head' x):_, which doesn't work on the left-hand side of an assignment.
We can't use brackets here because they would require knowing how many elements are in the list passed to head'.

Haskell :: The Use of Brackets in Recursion

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.

Count elements of each sublist

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.

Haskell pattern matching the first, middle section, and last

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.

Haskell: Minimum sum of list

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

Resources