pattern matching of negative literals in Haskell - haskell

I was trying to understand why n + k patterns were banned in Haskell. A famous post on StackOverflow gives an example of a function as follows:
f 0 = 0
f (n + 5) = 5
Haskell shows an error while matching f 1, f 2, f 3, f 4.
I cannot understand why (-1) cannot be matched with n. Firstly, I thought that integers only contain non-negative literals (0,1,..), but Haskell's definition of Int type includes negative literals.

Why can't -1 be matched? That's simply how n+k patterns were defined, presumably because it seemed like a good idea at the time. It's natural to use induction for natural numbers, so why not define our cool n+k patterns to work for naturals? From the Haskell report:
Matching an n+k pattern (where n is a variable and k is a positive integer literal) against a value v succeeds if x >= k, resulting in the binding of n to x - k, and fails otherwise. Again, the functions >= and - are overloaded, depending on the type of the pattern. The match diverges if the comparison diverges.
The fact that you found this surprising is probably one reason why n+k patterns were removed. Another is that there's no need for them: you can easily translate any n+k pattern into a pattern not using this feature.

Related

Exponentiation using list comprehension

I'm trying to solve the following exercise (I'm learning Haskell):
Define x^n using a list comprehension.
And I'm struggling to find a solution.
Using recursion or fold, the solution is not complicated (for instance, foldr (*) 1 [x | c <- [1..n]]). However, using only list comprehension it gets difficult (at least for me).
In order to solve the problem, I'm trying to create a list of x^n elements and then get the length. Generating a list of x*n elements is easy, but I fail to generate a list of x^n elements.
ppower x n = length [1 | p <- [1..x], c <- [1..n]]
returns a list of x*n elements giving a wrong result. Any ideas on this will be appreciated.
A naturally-occurring exponential comes from sequence:
length (sequence [[1..x] | _ <- [1..n]])
If you haven't seen sequence yet, it's quite a general function but
when used with lists it works like:
sequence [xs1, ... , xsk] = [[x1, ... xk] | x1 <- xs1, ... , xk <- xsk]
But this is really cheating since sequence is defined recursively.
If you want to use nothing but length and list comprehensions I think
it might be impossible. The rest of this answer will be sketchy and I half
expect someone to prove me wrong. However:
We'll try to prove that such an expression can only compute values up
to some finite power of x or n, and therefore can't compute values
as big as x^n for arbitrary x and n.
Specifically we show by induction on the structure of expressions that
any expression expr has an upper bound ub(expr, m) = m^k where m
is the maximum of the free variables it uses, and k is a known finite
power which we could calculate from the structure of the expression expr.
(When we look at the whole expression, m will be max x n.)
Our upper bounds on list expressions will be bounds on both the length of the list and also bounds on any of
its elements (and lengths of its elements, etc.).
For example if we have [x..y] and we know that x <= m and y <= m, we
know that all the elements are <= m and the length is also <= m.
So we have ub([x..y], m) = m^1.
The tricky case is the list comprehension:
[eleft | x1 <- e1, ... , xk <- ek]
The result will have length equal to length e1 * ... * length ek, so
an upper bound for it would be the product of the upper bounds for
e1 to ek, or if m^i is the maximum of these then an upper bound
would be (m^i)^k = m^(i*k).
To get a bound on the elements, suppose expression eleft has ub(eleft, m') = m'^j. It can use x1
... xk. If m^i is an upper bound for these, as above, we need to
take m' = m^i and so ub(eleft, m) = (m^i)^j = m^(i*j)
As a conservative upper bound for the whole list comprehension e we
could take ub(e, m) = m^(i*j*k).
I should really also work through cases for pattern matching
(shouldn't be a problem because the parts matched are smaller than
what we already had), let definitions and functions (but we banned
recursion, so we can just fully expand these before we start), and
list literals like [x,37,x,x,n] (we can throw their lengths
into m as initially-available values).
If infinite lists like [x..] or [x,y..] are allowed they would need some
thinking about. We can construct head and filter, which means we can get
from an infinite list to its first element matching a predicate, and that looks suspiciously like a way to get recursive functions. I don't
think it's a problem since 1. they are only arithmetic sequences and
2. we'll have to construct any numbers we want to use in the
predicate. But I'm not certain here.
As #n.m suggested, I asked Richard Bird (author of the book "Introduction to functional programming", first edition, the book where I got the exercise) for an answer/guidance in solving this exercise. He kindly replied and here I post the answer he gave me:
Since a list comprehension returns a list not a number, x^n cannot be
defined as an instance of a list comprehension. Your solution x^n =
product [x | c <- [1..n]] is the correct one.
So, I guess I'll stick to the solution I posted (and discarded for using recursion):
foldr (*) 1 [x | c <- [1..n]]
He didn't say anything about creating a list of x^n elements with lists comprehensions (no recursion) though as #David Fletcher and #n.m point out in their comments, it might be impossible.
May be you can do as follows;
pow :: Int -> Int -> Int
pow 0 _ = 1
pow 1 x = x
pow n x = length [1 | y <- [1..x], z <- [1..pow (n-1) x]]
so pow 3 2 would return 8

Using patterns to find the nth element

I'm working through Learn You A Haskell in order to come up to speed with the basics of Haskell. I'm very comfortable with both functional programming and pattern matching, but the latter more so with how Mathematica does it.
In the same spirit as the naïve implementation of head in Chapter 4.1, I proceeded with a naïve implementation of last as:
last1 :: [a] -> a
last1 (_:x:[]) = x
However, calling last1 [1,2,3,4] gave an error Exception: ... Non-exhaustive patterns in function last1. I understand that this error implies that the pattern specified does not cover all possible inputs and usually, a catch-all pattern is necessary (which I've not provided). However, I'm not exactly sure why I get this error for my input.
Question 1: My understanding (of my incorrect approach) is that the first element is captured by _ and the rest get assigned to x, which isn't exactly what I had intended. However, shouldn't this give a type error, because I specified [a] -> a, but x is now a list?
Note that this is not about how to write a working last function — I know I can write it as (among other possibilities)
last2 :: [a] -> a
last2 [x] = x
last2 (_:x) = last2 x
Question 2: Along the same theme of better understanding pattern matching in Haskell, how can I use pattern matching to pick out the last element or more generally, the nth element from a given list, say, [1..10]?
This answer suggests that you can bind the last element using pattern matching with the ViewPatterns extension, but it seems strange that there isn't an analogous "simple" pattern like for head
In Mathematica, I would probably write it as:
Range[10] /. {Repeated[_, {5}], x_, ___} :> x
(* 6 *)
to pick out the 6th element and
Range[10] /. {___, x_} :> x
(* 10 *)
to pick out the last element of a non-empty list.
I apologize if this is covered later in the text, but I'm trying to relate each topic and concept as I come across them, to how it is handled in other languages that I know so that I can appreciate the differences and similarities.
To make sense of the result of your first attempt, you need to see how the
list data is defined. Lists enjoy a somewhat special syntax, but you would
write it something like this.
data List a = (:) a (List a)
| []
So, your list [1 .. 10] is actually structured as
(1 : (2 : (3 : (4 : []))))
In addition, due to the right associativity of the (:) operator, your pattern
for last1 actually looks like
last1 :: [a] -> a
last1 (_:(x:[])) = x
That is why 'x' has same type as an element of your list; it is the first
argument to the (:) constructor.
Pattern matching allows you to deconstruct data structures like lists, but you
need to know what "shape" they have to do so. That is why you cannot directly
specify a pattern that will extract the last element of a list, because there
are an infinite number of lengths a list can have. That is why the working
solution (last2) uses recursion to solve the problem. You know what pattern
a list of length one has and where to find the final element; for everything
else, you can just throw away the first element and extract the last element
of the resulting, shorter, list.
If you wanted, you could add more patterns, but it would not prove that
helpful. You could write it as
last2 :: [a] -> a
last2 (x:[]) = x
last2 (_:x:[]) = x
last2 (_:_:x:[]) = x
...
last2 (x:xs) = last2 xs
But without an infinite number of cases, you could never complete the function
for all lengths of input lists. Its even more dubious when you consider the fact that
lists can actually be infinitely long; what pattern would you use to match that?
There is no way to have pattern match get the "last" element without using view patterns. That is because there is no way to get the last element of a list without using recursion (at least implicitly), and what is more, there is no decidable way to get the last element.
Your code
last1 (_:x:[]) = x
should be parsed like
last1 (_:(x:[])) = x
which can be de-sugared into
last1 a = case a of
(_:b) -> case b of
(x:c) -> case c of
[] -> x
having completed this exercise we see what your code does: you have written a pattern that will match a list IF the outermost constructor of a list is a cons cell AND the next constructor is a cons AND the third constructor is a nil.
so in the case of
last1 [1,2,3,4]
we have
last1 [1,2,3,4]
= last1 (1:(2:(3:(4:[]))))
= case (1:(2:(3:(4:[])))) of
(_:b) -> case b of
(x:c) -> case c of
[] -> x
= case (2:(3:(4:[]))) of
(x:c) -> case c of
[] -> x
= let x = 2 in case (3:(4:[])) of
[] -> x
= pattern match failure
Your example
last1 (_:x:[]) = x
only matches lists containing two elements i.e. lists of the form a:b:[]. _ matches the head of the list without binding, x matches the following element, and the empty list matches itself.
When pattern matching lists, only the right-most item represents a list - the tail of the matched list.
You can get the nth element from a list with a function like:
getNth :: [a] -> Int -> a
getNth [] _ = error "Out of range"
getNth (h:t) 0 = h
getNth (h:t) n = getNth t (n-1)
This built-in using the !! operator e.g. [1..10] !! 5
You can indeed use ViewPatterns to do pattern matching at the end of a list, so let's do:
{-# LANGUAGE ViewPatterns #-}
and redefine your last1 and last2 by reversing the list before we pattern match.
This makes it O(n), but that's unavoidable with a list.
last1 (reverse -> (x:_)) = x
The syntax
mainFunction (viewFunction -> pattern) = resultExpression
is syntactic sugar for
mainFunction x = case viewFunction x of pattern -> resultExpression
so you can see it actually just reverses the list then pattern matches that, but it feels nicer.
viewFunction is just any function you like.
(One of the aims of the extension was to allow people to cleanly and easily use accessor functions
for pattern matching so they didn't have to use the underlying structure of their data type when
defining functions on it.)
This last1 gives an error if the list is empty, just like the original last does.
*Main> last []
*** Exception: Prelude.last: empty list
*Main> last1 []
*** Exception: Patterns.so.lhs:7:6-33: Non-exhaustive patterns in function last1
Well, OK, not exactly, but we can change that by adding
last1 _ = error "last1: empty list"
which gives you
*Main> last1 []
*** Exception: last1: empty list
We can of course use the same trick for last2:
last2 (reverse -> (_:x:_)) = x
last2 _ = error "last2: list must have at least two elements"
But it would be nicer to define
maybeLast2 (reverse -> (_:x:_)) = Just x
maybeLast2 _ = Nothing
You can carry on this way with for example last4:
last4 (reverse -> (_:_:_:x:_)) = x
And you can see that using the reverse viewpattern,
we've changed the semantics of (_:_:_:x:_) from
(ignore1st,ignore2nd,ignore3rd,get4th,ignoreTheRestOfTheList) to
(ignoreLast,ignore2ndLast,ignore3rdLast,get4thLast,ignoreTheRestOfTheList).
You note that in Mathematica, the number of underscores is used to indicate the number of elements being ignored.
In Haskell, we just use the one _, but it can be used for any ignored value, and in the presence of the
asymmetric list constructor :, the semantics depend on which side you're on, so in a:b, the a must mean an
element and the b must be a list (which could itself be c:d because : is right associative - a:b:c means
a:(b:c)). This is why a final underscore in any list pattern reresents ignoreTheRestOfTheList, and in the
presence of the reverse viewfunction, that means ignoring the front elements of the list.
The recursion/backtracking that's hidden under the hood in Mathematica is explicit here with the viewFunction reverse (which is a recursive function).

Question about the ~ and # operators in Haskell

What exactly do they do? I know one possible use of # (assigning a name at the start of a pattern match), but haven't been able to find anything on ~.
I found them in the following code snippet, taken from http://www.haskell.org/haskellwiki/Prime_numbers, but the article assumes that you're fluent in Haskell syntax and doesn't bother explaining its esoteric operators (the part I'm confused about is the start of the declaration for sieve):
primesPT () = 2 : primes'
where
primes' = sieve [3,5..] primes' 9
sieve (p:xs) ps# ~(_:t) q
| p < q = p : sieve xs ps q
| True = sieve [x | x<-xs, rem x p /= 0] t (head t^2)
Any explanation (or link to one) about the syntax used here would be greatly appreciated.
The operator ~ makes a match lazy. Usually a pattern-match evaluates the argument, as there is a need to check whether the pattern fails. If you prefix a pattern with ~, there is no evaluation until it is needed. This functionality is often used in “Tying the knot” code, where one needs to refer to structures that are not yet created. If the pattern fails upon evaulation, the result is undefined.
Here is an example:
f (_:_) = True
f [] = False
g ~(_:_) = True
g [] = False
f [] yields False, while g [] yields true, because the first pattern always matches. (You actually get a warning for this code)
That said, you can see ~ as the opposite of !, which forces the evaluation of an argument even if it's unneeded.
Note that these operators only make things strict/lazy at the level they are applied at, not recursively. For example:
h ~((x,y):xys) = ...
The pattern match on the tuple is strict, but the cons pattern is lazy.
It's a lazy pattern match (also known as irrefutable pattern match which I think is the better name).
Essentially, ~(_:t) will always match, even if the input is the empty list []. Of course, this is dangerous if you don't know what you're doing:
Prelude> let f ~(_:t) = t in f []
*** Exception: <interactive>:1:4-15: Irrefutable pattern failed for pattern (_ : t)

Why is the recursion idiom in Haskell "'n+1' and 'n'" and not "'n' and 'n-1'"?

I'm working my way through Graham Hutton's Haskell book, and in his recursion chapter, he often pattern-matches on "n+1", as in:
myReplicate1 0 _ = []
myReplicate1 (n+1) x = x : myReplicate1 n x
Why that and not the following, which (1) seems functionally identical and (2) more intuitive in terms of understanding what's happening with the recursion:
myReplicate2 0 _ = []
myReplicate2 n x = x : myReplicate2 (n-1) x
Is there something I'm missing here? Or is it just a matter of style?
Those are n+k patterns (that should be avoided!) in the first function. Both functions do the same thing, except for the n+k one not matching negative numbers. The latter one, however, is recommended, and can be adopted if you want no negative numbers on purpose, because the n+k patterns are sheduled to be removed anyways.
So no, you're missing nothing, and it is indeed a matter of style, but I rarely see n+k patterns in the wild.
I think the idea behind it is this: We can define a type for the natural numbers (0, 1, ...) like this:
data Natural = Z -- zero
| S Natural -- one plus a number; the next number; the "successor"
0 = Z, 1 = S Z, and so on. This system is called Peano arithmetic, and is pretty much a standard in mathematics as a (starting point for a) definition of what a "number" actually is. You can go on to define Integers as pairs(-ish) of Naturals, and so on.
When you do this, it becomes natural to use pattern matching like this:
myReplicate1 Z _ = []
myReplicate1 (S n) x = x : myReplicate1 n x
I think (and it's just a guess) that the idea behind n+1 patterns is a machine version of what I just described. So, n+1 is to be thought of like the pattern S n. If you're thinking this way, n+1 patterns seem natural. This also makes it clear why we have the side condition that n >= 0. We can only represent n >= 0 using the type Natural.
N+K patterns also have different strictness implications.
For example:
f (n+1) = Just n
g n = Just (n-1)
f is strict on its first argument, g is not. This is nothing special with n+k patterns but applies to all patterns.
n+k patterns only match when n>=0. So in your myReplicate1 the n+1 pattern will match only positive numbers and a negative n will cause a nonexhaustive-pattern exception. In myReplicate2 a negative n would create an infinite list.
So in other words you can use n+k patterns when you don't want the pattern to match negative numbers, but using a guard instead will be clearer.
myReplicate n x = take n (repeat x)
Done and done. :D

What is the difference between an operator and a function in Haskell?

I am new to Haskell and this mixture of Infix and Prefix notation is confusing me.
What is the difference between an operator like '+' and a function like head? How do I write an operator 'c' which does this 1 c 1 = 2?
I found this definition a ! b = True. How does Haskell know that I am defining ! and not a function a?
In Haskell, to create an operator you must use the following "operator symbols":
! # $ % * + . / < = > ? \ ^ | : - ~
So, for example
($$$) a b = a+b
Defines an operator $$$ which can be used in the expression 1 $$$ 1 to yield a value of 2.
Conceptually, there is no difference between an operator and a function, and you can use backticks or parens to make one work like the other.
EDIT:
Just so it is 100% clear, let me demonstrate turning a function into an operator and vice versa:
For the operator '+', the following two expressions are equivalent:
1+1
(+) 1 1
Similarly, for a function, the following two expressions are equivalent:
foo 1 2
1 `foo` 2
Haskell knows you aren't defining a function called a because the ! wouldn't be valid in a function argument list. In order to use the ! not as an operator but just as a normal identifier, you need to enclose it in parentheses. If you wrote instead a (!) b = True, then it would define the function a :: t -> t1 -> Bool.
This is the entire difference between operators and normal identifiers in Haskell — there are special syntax rules for operators that allow them to be used infix without backticks. Otherwise, they're just functions.
Really, the only difference is syntax. Function names begin with a lower-case letter, followed by a series of alpha-numeric characters. Operators are some unique sequence of the typical operator characters (+ - / * < > etc.).
Functions can be used as operators (in-fix) by enclosing the function name in ` characters. For example:
b = x `elem` xs -- b is True if x is an element in xs.
Operators can be used as functions (pre-fix) by enclosing the operator in parens. For example:
n = (+) 2 5 -- n = 2 + 5, or 7.

Resources