Prelude.&&
(Prelude.||)
[*]Prelude.fst
Notice that the not
function has two rules:
True
, then the function returns False
.False
, then the function returns True
.When you run a function, only one rule can run. Haskell runs the first matching rule.
A pattern may be:
x
, xs
, y
, a
, foobar
… These names match any value, and can be used in the rule’s body._
This symbol matches any value, and cannot be used in the rule’s body. It is a “don’t care” value.True
, 0
, (a, b)
, "hello"
… Only values matching the given pattern are accepted.Usually, a function should match all possible values. For example, in the not
function above, the possible values are True
and False
, and we have a rule for both. What happens if call the function with a value for which there is no rule?
Try calling addOne
with the parameter 5
.
How can we fix the above function?
Prelude.&&
Here is a possible definition of the logical AND operation:
(&&) :: Bool -> Bool -> Bool
True && True = True
True && False = False
False && True = False
False && False = False
Logical AND implemented in a different way:
Logical AND implemented in yet another different way:
(Prelude.||)
[*]Redefine the (||)
operator.
Here, we will have to hide the original definition of (||)
.
In place of the dots, there may be further definitions to hide.
Define the exclusive OR function.
Prelude.fst
Pattern for matching pairs: (
x,
y)
.
For example:
Usage:
Swap two elements of a pair. Use pattern matching on a tuple.
Reflect a point in the X axis.
Let scale' t
be a scaling by t
in the origin. The magnitude of the point will increase by the given value.
Reflect a point around another point. The first point acts as an origin; the second point is reflected to its opposite side. See the examples below.
Calculate the distance of two points.
You can use the absolute value function:
You can use the square root function:
Values can be used to match patterns in function parameters of different types. For example:
Integer
: …, -2
, -1
, 0
, 1
, 2
, …
Double
: …, -2
, -1
, 0
, 1
, 2
, …, 4.3
, …
Char
: 'x'
, '\n'
, …
String
: ""
, "abc"
, …
Define modulo 3 multiplication. This means that for every x
and y
between 0 and 3, this expression will be true:
x `mul3` y == (x * y) `mod` 3
Use pattern matching to achieve this. Do not use the mod
function or multiplication operator in your solution!
Define a function that replaces a line break with a space, and otherwise returns the same value. Recall that ‘’ is the character value for a newline.
Define a function that replaces all line breaks with spaces. Use replaceNewline
.
Define a function that replaces the words “this” and “that” and vice versa.
Define a function that swaps all instances of “this” and “that”.
Hint: Use the words
and unwords
functions.
We have shown that we can match patterns for Strings, Ints, tuples, etc. We can also match lists. In particular, we can express requirements about the size of the list. Only a list matching the requirements will invoke the function’s rule:
Match any list: a
Match an empty list: []
Match a list with exactly one item (“singleton”): [a]
Match a list with exactly two items: [a,b]
Match a list with exactly three items: [a,b,c]
Match a non-empty list: (a:b)
Note that when we use a pattern like [a,b]
, the name a
refers to the first item in the list, and the name b
refers to the second item in the list. When we use a pattern like (a:b)
, a
refers to the first item in the list, and b
refers to the rest of the list; therefore b
will be a (possibly empty) list.
For example (functions from the Prelude
):
null
returns True
when its parameter is an empty list.
head
returns the first item of a list.
tail
returns all items of a list except the first.
Usage:
Two basic patterns for lists that could be used to build more complex list patterns are as follows.
[]
(h:t)
In the h:t
pattern, the h
and t
may be arbitrary patterns, i.e. this is a complex pattern.
Semantics:
[]
pattern matches only the empty list.h:t
pattern matches only if the list is not empty: the h
matches the head of the list, while t
matches the tail of the list.Type of the “colon”:
Thus if the type of h:t
is [x]
then the type of h
is x
, and the type of t
is [x]
.
The colon operator is right-associative.
Define a function that tests the given list is a singleton one. Use pattern matching.
Convert the initial letter of an arbitrary word to uppercase.
Hint: use the function toUpper
:
Convert the initial letter of every word in a string to uppercase.
Hint: use your toUpperFirst
function and words
and unwords
Patterns can be even employed in list comprehensions. Here is an intuitive example for this:
Count the “a” words in a text.
Count pairs in a list where the distance between the components is greater than or equal to 2.
Take every fifth element of a list.
Hint: Use the zip
function.