Understanding the Haskell as-pattern - haskell

I'm reading through Real World Haskell, and am trying to understand the as-pattern.
From the book (Chapter 4):
suffixes :: [a] -> [[a]]
suffixes xs#(_:xs') = xs : suffixes xs'
suffixes _ = []
The book explains the # symbol thus,
"...bind the variable xs to the value that matches the right side of the
# symbol."
I'm having trouble understanding this explanation.
Supposing I call
suffixes "hello"
Explicitly, what would the above line with the # do to this (on the first iteration)? I know what the result of the function is, but cannot see how we get there from the above code.

xs' would be bound to the string "ello".
xs would be bound to the string "hello".
The # pattern lets you give a name to a variable while also matching its structure and possibly giving name to the components.

Perhaps an actual "de-sugaring" will make it easier to understand:
suffixes xs#(_:xs') = xs : suffixes xs'
is equivalent to
suffixes xs
| (_:xs') <- xs = xs : suffixes xs'
i.e. you're firstly binding the entire argument to the variable xs, but you also do pattern matching on the same argument (or, equivalently, on xs) to (_:xs').

Related

Haskell last string

I'm trying to make a function that takes the last character from a string and add it to be the first character. In string I can do this (xs:x) and then x is the last character?
xs is just a naming convention for lists in Haskell (which you should use!). (x:xs) is a pattern matching using the (:) function, it is up to you how you name it e.g. (this:makesnosense) is also valid.
Also remember that a String is just another list, so your question is equal to: "How can I make the last element of a list the first one."
This would be one way to solve it:
lastToFirst :: [a] -> [a]
lastToFirst [] = []
lastToFirst [x] = [x]
lastToFirst xs = last xs : init xs
I'm trying to make a function that takes away the last character from a string and add it to be the first character.
In Haskell, list operator ':' is asymmetric. If the left operand is of type α, the right operand must be of type [α]. Hence, a pattern such as xs:x is just using misleading variable names. The operator is right-associative, so that x0:x1:xs means x0:(x1:xs).
Unlike Python lists, which are basically arrays, Haskell lists are just forward-chained linked lists. Classic imperative languages often maintain both a pointer to the head of a linked list and to its tail, but the main point of the tail pointer is to be able to append new elements at the tail of the list.
As Haskell lists are immutable, the tail pointer would be mostly useless, and so Haskell only maintains a pointer to the head of a list.
This means there is no cheap way to access the last element. The only way is to traverse the whole list, starting from the head. Furthermore, immutability implies that the only way to generate the [1,2,3] list from the [1,2,3,4] list is by duplicating the first 3 elements, which again require a full traversal.
So an expression such as last xs : init xs, if compiled naïvely, implies 2 costly traversals of the input list.
The best one can hope is to leverage the duplication work to grab the last element at no extra cost, thus solving the problem in a single traversal. This can be done, for example, by recursion:
makeLastFirst :: [a] -> [a]
makeLastFirst [] = [] -- empty input list
makeLastFirst [end] = [end] -- just the last element
makeLastFirst (x0:(x1:xs)) = let (end:ys) = makeLastFirst (x1:xs)
in end : (x0:ys)
where the recursive clause takes care of keeping the input tail element at the head of the output list.
Watching the gears turn:
One can visualize the recursive process by importing package Debug.Trace and using its trace function. Expression trace msg value evaluates to just value, but has the side effect of printing the msg string. Yes, side effects are normally forbidden in Haskell, but function trace has special privileges.
So we can write a more talkative version of our function:
import Debug.Trace
traceMakeLastFirst :: Show a => [a] -> [a]
traceMakeLastFirst [] = [] -- empty input list
traceMakeLastFirst [end] = [end] -- just the last element
traceMakeLastFirst (x0:(x1:xs)) = let (end:ys) = traceMakeLastFirst (x1:xs)
result = end : (x0:ys)
in trace (show result) result
Testing under the ghci interpreter:
$ ghci
GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help
λ>
λ> :load q66927560.hs
...
Ok, one module loaded.
λ>
λ> traceMakeLastFirst ""
""
λ>
λ> traceMakeLastFirst "a"
"a"
λ>
λ> makeLastFirst "Mercury"
"yMercur"
λ>
λ> traceMakeLastFirst "Mercury"
""yr"
"yur"
"ycur"
"yrcur"
"yercur"
"yMercur"
yMercur"
λ>
-- makeLastFirst "abcd" == "dabc"
-- makeLastFirst "hello" == "ohell"
-- makeLastFirst "orange" == "eorang"
makeLastFirst :: [a] -> [a]
makeLastFirst lst = [ head (reverse lst) ] ++ (init lst)

Non-exhaustive patterns, Haskell

I am trying to write the function tails, which converts a string into a list of strings in the following way:
tails "abc" = ["abc", "bc", "c", ""]
Here is my implementation:
tails :: [Char] -> [[Char]]
tails (x:xs)
| length (x:xs) == 0 = [""]
| otherwise = (x:xs) : tails xs
As the title suggests, there are non-exhaustive patterns in this function. Unfortunately, I don't see how so.
I am new to Haskell... Any help would be appreciated!
The pattern is non-exhaustive because it can't accept []. A list has form of either [] or a:as, where a is the leading element and as is the list of the trailing elements. So the pattern x:xs matches only if the list has a leading element. Fixing that gives:
tails :: [Char] -> [[Char]]
tails xs
| length xs == 0 = [""]
| otherwise = let (_:xs') = xs in xs : tails xs'
And then xs accepts the list regardless of its form.
But this is inefficient due to length, and doesn't work for infinite lists.
This should fully work, which directly does pattern mathing:
tails :: [Char] -> [[Char]]
tails [] = [""]
tails xs#(_:xs') = xs : tails xs'
What about trying this or at least get some logic from it. It works well.
It's got a helper function to convert the string into a list of separate characters, for example "abc" becomes ["a","b","c"]. It is just less complicated to process them like that and it becomes necessary to collect distinct strings in the result list. There are two functions in the function set and a third is warranted to call the primary function with one parameter. The primary function is on one line but uses guards.
ca = [[c] | c <- "abcdef"]
f (l1,ls) | null ls = l1++[[]] | True = f ( l1 ++ [concat ls], (tail ls))
f ([],ca)
["abcdef","bcdef","cdef","def","ef","f",""]
Edit 4/4/2018
I was wrong. The list parameter does not have to be made into a list before hand. By not doing so, the function becomes simpler by removing the concat function and changing the parameter list from tuple to individual removed lots or parentheses.
fs l1 ls = if null ls then l1++[""] else fs (l1++[ls]) (tail ls)
It is invoked differently, too.
fs [] "Hello!"
This, by itself, produced the right results.
Edit/add 4/11/2018
What keeps recurring (no pun) is dependence on tail when Haskell splits up input into head and tail with (x:xs) they are ready to use. Here is a basic recursive function that uses (x:xs) only for head and tail. I produces all tails of input list including null.
t [] = [""]; t (x:xs) = [x:xs] ++ t xs
And yet another that takes a list as the only parameter.
t ls = [drop n ls|n<-[0..length ls - 1]]

separate List by heads

I have problems trying to separate a list follows, suppose we have the following lists
[[1,2,3,4], [5,6,7,8], [9,10,11,12 ], [13,14,15,16,17]].
The result should be:
[[1,5,9,13] [2,6,10,14] [3,7,11,16] [4,8,12,16]]
I'm trying to do it the following way:
joinHead (x: xs) = map head (x: xs)
separateLists (x: xs) = xs joinHead x ++ separateLists
obviously this does not work. I hope you can help me. thx.
I adapted the functions you wrote, joinHead and separateLists, to make the code work, while preserving the logic you were following. From what I could infer looking at these functions, the idea was to use joinHead to extract the first element of each child list and return a new list. Then, this new list should be inserted in the front of a list of lists returned from calling separateLists recursively.
Here is the new definition of joinHead:
joinHead :: [[a]] -> [a]
joinHead ([]:_) = []
joinHead xs = map head xs
Note that the first line checks, through pattern matching, whether the first list contained in the list of lists is empty and, if so, returns an empty list ([]). The reasons for that are two:
The function head is unsafe. That means that calling head on an empty list will cause an exception to be thrown (try running in GHCi head []);
For simplicity, I'm assuming that all the lists were already checked to have the same length (length (xs !! 0) == length (xs !! 1) ...).
The definition of separateLists is as follows:
separateLists :: [[a]] -> [[a]]
separateLists ([]:_) = []
separateLists ([x]:xs) = [joinHead ([x]:xs)]
separateLists xs = joinHead xs : separateLists (map tail xs)
Again, the first two definitions are necessary for both stopping the recursion and safety purposes. The first line says: "if the first list is empty, then all the elements of all lists were already consumed, so return []". The second line says: "if the first line has exactly one element, then just call joinHead and return the result wrapped in a list". Note that in the third definition we have a call to tail which, like head, throws exceptions when called on []. That's the reason of why we need a separate case for lists of length 1. Finally, the third line, which is executed for lists of length greater than 1, gets a list from joinHead xs and insert it (using the "cons" operator (:)) in the beginning of the list returned from recursively calling separateLists. In this call, we have to take out the first elements of all the lists, that's why we use map tail xs.
Now, running:
λ: let list = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16,17]]
λ: separateLists list
[[1,5,9,13],[2,6,10,14],[3,7,11,15],[4,8,12,16]]
will give you the expected results. I hope it was clear enough. As a final note, I want to point out that this implementation is far from being optimal and, as suggested in the comments, you should probably use the standard Data.List.transpose. As an exercise and didatic example, it's fine! ;-)

H-99 Problems: #26 Can't Understand The Solution

I am currently working through H-99 Questions after reading Learn You a Haskell. So far I felt like I had a pretty good grasp of the concepts, and I didn't have too much trouble solving or understanding the previous problems. However, this one stumped me and I don't understand the solution.
The problem is:
Generate the combinations of K distinct objects chosen from the N elements of a list
In how many ways can a committee of 3 be chosen from a group of 12 people? We all know that there are C(12,3) = 220 possibilities (C(N,K) denotes the well-known binomial coefficients). For pure mathematicians, this result may be great. But we want to really generate all the possibilities in a list.
The solution provided:
import Data.List
combinations :: Int -> [a] -> [[a]]
combinations 0 _ = [ [] ]
combinations n xs = [ y:ys | y:xs' <- tails xs, ys <- combinations (n-1) xs']
The main point of confusion for me is the y variable. according to how tails works it should be getting assigned the entire list at the beginning and then that list will be preppend to ys after it is generate. However, when the function run it return a list of lists no longer than the n value passed in. Could someone please help me understand exactly how this works?
Variable y is not bound to the whole xs list. For instance, assume xs=[1,2,3]. Then:
y:xs' is matched against [1,2,3] ==> y=1 , xs'=[2,3]
y:xs' is matched against [2,3] ==> y=2 , xs'=[3]
y:xs' is matched against [3] ==> y=3 , xs'=[]
y:xs' is matched against [] ==> pattern match failure
Note that y is an integer above, while xs' is a list of integers.
The Haskell code can be read a a non-deterministic algorithm, as follows. To generate a combination of n elements from xs, get any tail of xs (i.e., drop any number of elements from the beginning). If the tail is empty, ignore it. Otherwise, let the tail be y:xs', where y is the first element of the tail and xs' the remaining (possibly empty) part. Take y and add it to the combination we are generating (as the first element). Then recursively choose other n-1 arguments from the xs' remaining part, and add those to the combination as well. When n drops to zero, we know there is only one combination, namely the empty combination [], so take that.
y is not appended to ys. That would involve the (++) :: [a] -> [a] -> [a] operator.
For that matter the types would not match if you tried to append y and ys. y has type a, while ys has type [a].
Rather, y is consed to ys using (:) :: a -> [a] -> [a] (the cons operator).
The length of the returned list is equal to n because combinations recurses from n to 0 so it will produce exactly n inner lists.

Exception : Pattern Matching failure Haskell

I am trying to implement Standard words function of Haskell. I am using State Monad to solve the problem.
My Code is :
type WorS = ([String],String,String)
words' :: State WorS [String]
words' = do
(lwords, words, x:xs) <- get
case x:xs of
(' ':xs) -> (put (words:lwords, [], xs) >> words')
([]) -> return lwords
(_:xs)-> (put (lwords, words ++ [x], xs) >> words')
run_word' :: String ->[String]
run_word' x = reverse $ fst (runState words' ([], [], x))
When I do:
run_word' "guns and roses"
I get this error:
Exception: Pattern match failure in do expression
The code is loading in ghci without any error. What am I doing wrong?
(lwords,words,x:xs)<-get
x:xs matches a list with at least one element (x becomes the first element, and xs becomes the rest of the list), so you get a pattern match failure when the third member of the tuple is [].
Solution: replace
(lwords,words,x:xs)<-get
case x:xs of
with
(lwords,words,xs)<-get
case xs of
(And consider using different variable names later in the function: it gets confusing when you have two or more variables with the same name.)
Edit: if you turn on warnings (pass the -Wall flag to ghc/ghci), you will get warned at compile time that the pattern may fail to match at runtime. (You'll also get a warning about having one xs variable hiding another xs variable, called shadowing.)

Resources