Explanations about the mechanics of a simple factorial function - haskell

I'm new to Haskell, so I'm both naive and curious.
There is a definition of a factorial function:
factorial n = product [1..n]
I naively understand this as: make the product of every number between 1 and n. So, why does
factorial 0
return 1 (which is the good result as far as my maths are not too rusted)?
Thank you

That's because of how product is defined, something like:
product [] = 1
product (n:ns) = n * product ns
or equivalently
product = foldr (*) 1
via the important function foldr:
foldr f z [] = z
foldr f z (x:xs) = f x (foldr f z xs)
Read up on folding here. But basically, any recursion must have a base case, and product's base case (on an empty list) clearly has to be 1.

The story about empty product is long and interesting.
It has many sense to define it as 1.
Despite of that, there is some more debate about whether we are justified to define 00 as 1, although 00 can be thought of also as an empty product in most contexts. See the 00 debate here and also here.
Now I show an example, when empty product conventions can yield a surprising, unintuitive outcome.
How to define the concept of a prime, without the necessity to exclude 1 explicitly? It seems so unaesthetic, to say that "a prime is such and such, except for this and that". Can the concept of prime be defined with some handy definition which can exclude 1 in a "natural", "automatic" way, without mentioning the exclusion explicitly?
Let us try this approach:
Let us call a natural number c composite, iff c can be written as a product of some a1, ..., ⋅ an natural numbers, so that all of them must be different from c.
Let us call a natural number p prime, iff p cannot be written as a product of any a1, an natural numbers each differing from p.
Let us test whether this approach is any good:
6 = 6 ⋅ 1 3 ⋅ 26 is composite, this fact is witnessed by the following factorisation: 6 can be written as the product 3 ⋅ 2, or with other words, product of the ⟨3, 2⟩ sequence, notated as Π ⟨3, 2⟩.
Till now, our approach new is O.K.
5 = 5 ⋅ 1 1 ⋅ 55 is prime, there is no sequence ⟨a1, ... an⟩ such that
all its members a1, ... an would differ from 5
but the product itself, Π ⟨a1, ... an⟩ would equal 5.
Till now, our new approach is O.K.
Now let us investigate 1:
1 = Π ⟨⟩,
Empty product is a good witness, with it, 1 satisfies the definition of being a composite(!!!) Who is the witness? Where is the witnessing factorization? It is no other than the empty product Π ⟨⟩, the product of the empty sequence ⟨⟩.
Π ⟨⟩ equals 1
All factors of the empty product Π ⟨⟩, i.e. the members of the empty sequence ⟨⟩ satisfy that each of them differ from 1: simply because empty sequence ⟨⟩ does not have any members at all, thus none of its member can equal 1. (This argumentation is simply a vacuous truth, with members of the empty set).
thus 1 is a composite (with the trivial factorization of the Π ⟨⟩ empty product).
Thus, 1 is excluded being a prime, naturally and automatically, by definition. We have reached our goal. For this, we have exploited the convention about empty product being 1.
Some drawbacks: although we succeeded to exclude 1 being a prime, but at the same time, 0 "slipped in": 0 became a prime (at least in zero-divisor free rings, like natural numbers). Although this strange thing makes some theorems more concise formally (Goldbach conjecture, fundamental theorem of arithmetic), but I cannot stand for that it is not a drawback.
A bigger drawback, that some concepts of arithmetic seem to become untenable with this new approach.
In any case, I wanted only to demonstrate that defining the empty product as 1 can yield formalizing unintuitive things (which is not necessarily a problem, set theory abounds with unintuitive things, see how to produce gold for free), but at the same time, it can provide useful strength in some contexts.

It's traditional to define the product of all the elements of the empty list to be 1, just as it's traditional to define the sum of all the elements of the empty list to be 0. That way
(product list1) * (product list2) == product (list1 ++ list2)
among other convenient properties.
Also, your memory is correct, and 0! is defined to be 1. This also has many convenient properties, including being consistent with the definition of factorials in terms of the gamma function.

Not sure I understand your question, are you asking how to write such a function?
Just as an exercise, you could use pattern matching to approach it like this:
factorial :: Int->Int
factorial 0 = 1
factorial n = product [1..n]
The first line is the function declaration/type signature. The second two lines are equations defining the function - Haskell pattern matching matches up the actual runtime parameter to whichever equation is appropriate.
Of course as others have pointed out, the product function handles the zero case correctly for you.

Related

Haskell List Comprehension, delete integers from List of numbers

i want to implement a function in list comprehension.
It should deletes the integers in a list of numbers.
And i have a question about it.
delete xs = [ys|ys<-xs, ys /=fromInteger (round ys) ]
xxx.hs> delete [1,2,3.0,4.5,6.7]
[4.5,6.7]
is that means 3.0 is counted as integer instead of float?
And another question:
delete xs = [ys|ys<-xs, ys ==fromInteger (round ys) ]
this time i want it to return integers from a list of numbers.
xxx.hs> delete [1,2,3.0,4.5,6.7]
[1.0,2.0,3.0]
since i did not give the number 1 and 2 in decimal form, why it returns the numbers in decimal?
Thanks for helping me.
I want to implement a function in list comprehension. It should deletes the integers in a list of numbers.
In a list all elements have the same type. So in a list [1.2, 3, 4.5], the 3 is also a value of a type that is a member of the Floating typeclass.
Since i did not give the number 1 and 2 in decimal form, why it returns the numbers in decimal?
Because all the elements are of the same type. GHC will default to Double by the type defaulting rules.
Your filter does not specify that elements should be of an Integral type. This would also be non-sensical since types are resolved at compile time, not at runtime. It simply checks that ys is the same if you fromInteger (round ys). Since round 3.0 == 3, and fromInteger 3 == 3.0 in this case, it thus filters out elements with a fractional part. 1.0 and 2.0 have no fractional part.
The filtering is however not safe, for larger numbers, the mantisse can not represent every integer exactly, and thus this means that some values will be filtered retained when these are not integeral numbers. For more information, see is floating point math broken.

Why sum of products can be viewed as normal form in algebraic data types?

I am reading a haskell book (page 412). In this book, there is an explanation about normal form for sum of products:
All the existing algebraic rules for products and sums apply in type systems, and that includes the distributive property. Let’s take a look at how that works in arithmetic:
2 * (3 + 4)
2 * (7)
14
We can rewrite this with the multiplication distributed over the addition and obtain the same result:
2 * 3 + 2 * 4
(6) + (8)
14
This is known as a “sum of products.” In normal arithmetic, the expression is in normal form when it’s been reduced to a final result. However, if you think of the numerals in the above expressions as representations of set cardinality, then the sum of products expression is in normal form, as there is no computation to perform.
I've known that a normal form indiciates that an expression is fully reduced. In the above description, author of the book explains that sum of products can be seen as in normal form when we think of expression as representations of set cardinality. I don't understand that.
Cardinality of types means how many different values can be included in that type (like set). For example, Bool type in haskell has cardinality of 2, which is addition of 1 for False and 1 for True each.
Is sum of products (2 * 3 + 2 * 4) a normal form? This expression can be reduced furthre more because fully reduced expression would be 14. I don't understand why sum of products and cardinality of it are related to be normal form.
Let's declare ourselves some types to represent the numbers:
data Two = OneOfTwo | TwoOfTwo
data Three = OneOfThree | TwoOfThree | ThreeOfThree
data Four = ... (similar)
Now we can see that the number of possible values of type Two is, in fact, 2. Same for Three, Four, and Seven.
Now if we construct a sum type:
data A = A Two
This type just straight up wraps a value of Two, so the number of possible values of A is also 2. So far so good?
Now let's construct a more complex one:
data B = B1 Three | B2 Four
Now, this type wraps either a value of type Three or a value of type Four (but not both at the same time!) This means that the number of possible values would be 3 + 4. Following so far?
Now, going further:
data C = C Two B
This type wraps two values at the same time - one value of type Two and one value of type B. This means that the number of possible values of C is the number of possible combinations of Two and B, which, as we know from middle-school mathematics, would be their product, or 2 * (3 + 4) = 2 * (7) = 14.
But here's the trick: we can write down an equivalent type in a different way:
data CNew = C1 Two Three | C2 Two Four
See what I did there? For CNew, the set of all possible combinations between values of Two, Three, and Four is the same as for C. Look: in both cases it's either a value of Two combined with a value of Three, or it's a value of Two combined with a value of Four. Except in CNew they're combined directly, but in C they're combined via B.
But the formula for CNew would be different: 2 * 3 + 2 * 4 = (6) + (8) = 14. This is what the book means.
Now to answer this bit more directly:
Is sum of products (2 * 3 + 2 * 4) a normal form? This expression can be reduced further more because fully reduced expression would be 14
This would be true if we were dealing with integer numbers, but we're not. We can rewrite C in the form of CNew, because that gives us all the same possible combinations of values. But we cannot rewrite them as a type that has straight up 14 possible values without combining 2, 3, and 4. That would be a completely new, unrelated type, as opposed to a combination of Two, Three, and Four.
And a possible terminology misunderstanding:
Is sum of products (2 * 3 + 2 * 4) a normal form?
The term "normal form" doesn't mean "the shortest". This term is usually used to denote a form that is very regular, and therefore easier to work with, and, crucially, that can represent all possible cases in the domain. In this case, normal form is defined as a "sum of products".
Could it be a "product of sums" instead? No, it couldn't, because, while a product of sums can always be converted to a sum of products, the reverse is not always possible, and this means that not every possible type would be representable in the normal form defined as "product of sums".
Could it be "just the number of possible values", like 14? Again no, because converting to such form loses some information (see above).

Counting quantifiers - how

Let's say, I have to model a checkerboard and I want to say that at least 5 squares on the "A" vertical are empty. How do I do that in Alloy? Any other example with numbers different from 0 or 1 would be good. In other words, what do I do when "some" is not precise enough?
Thanks!
You can use the cardinality operator (#) to make assertions about the number of tuples in a relation, e.g.,
#r >= 5
says that the relation r must have at least 5 tuples.
You can also use the cardinality operator with an arbitrary expression, e.g.,
#board.cells >= 5
or
#{c: Cell | c in board.cells and ...} >= 5

string Rabin-Karp elementary number notations

I am reading about String algorithms in Introduction to Algorithms by Cormen etc
Following is text about some elementary number theoretic notations.
Note: In below text refere == as modulo equivalence.
Given a well-defined notion of the remainder of one integer when divided by another, it is convenient to provide special notation to indicate equality of remainders. If (a mod n) = (b mod n), we write a == b (mod n) and say that a is equivalent to b, modulo n. In other words, a == b (mod n) if a and b have the same remainder when divided by n. Equivalently, a == b (mod n) if and only if n | (b - a).
For example, 61 == 6 (mod 11). Also, -13 == 22 == 2 == (mod 5).
The integers can be divided into n equivalence classes according to their remainders modulo n. The equivalence class modulo n containing an integer a is
[a]n = {a + kn : k Z} .
For example, [3]7 = {. . . , -11, -4, 3, 10, 17, . . .}; other denotations for this set are [-4]7 and [10]7.
Writing a belongs to [b]n is the same as writing a == b (mod n). The set of all such equivalence classes is
Zn = {[a]n : 0 <= a <= n - 1}.----------> Eq 1
My question in above text is in equation 1 it is mentioned that "a" should be between 0 and n-1, but in example it is given as -4 which is not between 0 and 6, why?
In addition to above it is mentioned that for Rabin-Karp algorithm we use equivalence of two numbers modulo a third number? What does this mean?
I'll try to nudge you in the right direction, even though it's not about programming.
The example with -4 in it is an example of an equivalence class, which is a set of all numbers equivalent to a given number. Thus, in [3]7, all numbers are equivalent (modulo 7) to 3, and that includes -4 as well as 17 and 710 and an infinity of others.
You could also name the same class [10]7, because every number that is equivalent (modulo 7) to 3 is at the same time equivalent (modulo 7) to 10.
The last definition gives a set of all distinct equivalence classes, and states that for modulo 7, there is exactly 7 of them, and can be produced by numbers from 0 to 6. You could also say
Zn = {[a]n : n <= a < 2 * n}
and the meaning will remain the same, since [0]7 is the same thing as [7]7, and [6]7 is the same thing as [13]7.
This is not a programming question, but never mind...
it is mentioned that "a" should be between 0 and n-1, but in example it is given as -4 which is not between 0 and 6, why?
Because [-4]n is the same equivalence class as [x]n for some x such that 0 <= x < n. So equation 1 takes advantage of the fact to "neaten up" the definition and make all the possibilities distinct.
In addition to above it is mentioned that for Rabin-Karp algorithm we use equivalence of two numbers modulo a third number? What does this mean?
The Rabin-Karp algorithm requires you to calculate a hash value for the substring you are searching for. When hashing, it is important to use a hash function that uses the whole of the available domain even for quite small strings. If your hash is a 32 bit integer and you just add the successive unicode values together, your hash will usually be quite small resulting in lots of collisions.
So you need a function that can give you large answers. Unfortunately, this also exposes you to the possibility of integer overflow. Hence you use modulo arithmetic to keep the comparisons from being messed up by overflow.

Ranges in Haskell (GHCi)

I'm reading Learn You A Haskell for Great Good. His examples [2,2..20] and [3, 6..20] work fine but I got three weird results:
Count by 17's from one to 171: [17, 1..171] yields the null list.
Count by 17's from seventeen to 1711111: [17, 17..171111] repeats the number 17 until I interrupt GHCi.
There is a weird difference between take 54 [171, 234..] and take 54 [171, 244..]:
ghci> take 54 [171, 234..]
[171,234,297,360,423,486,549,612,675,738,801,864,927,990,1053,1116,1179,1242,1305,1368,1431,1494,1557,1620,1683,1746,1809,1872,1935,1998,2061,2124,2187,2250,2313,2376,2439,2502,2565,2628,2691,2754,2817,2880,2943,3006,3069,3132,3195,3258,3321,3384,3447,3510]
ghci> take 54 [171, 244..]
[171,244,317,390,463,536,609,682,755,828,901,974,1047,1120,1193,1266,1339,1412,1485,1558,1631,1704,1777,1850,1923,1996,2069,2142,2215,2288,2361,2434,2507,2580,2653,2726,2799,2872,2945,3018,3091,3164,3237,3310,3383,3456,3529,3602,3675,3748,3821,3894,3967,4040]
Why?
You have the meaning of ranges slightly off. The Haskell range syntax is one of four things: [first..], [first,second..], [first..last], [first,second..last]. The examples from Learn You A Haskell are
ghci> [2,4..20]
[2,4,6,8,10,12,14,16,18,20]
ghci> [3,6..20]
[3,6,9,12,15,18]
Note that in the first case, the list counts by twos, and in the second case, the list counts by threes. That's because the difference between the first and second items is two and three, respectively. In your syntax, you're trying to write [first,step..last] to get the list [first,first+step,first+2*step,...,last]; however, the step size of a range like that is actually the difference between the first two numbers. Without a second element, the step size is always one; and without a final element, the list goes on forever (or until the maximum/minimum element of the type is reached).
Thus, let's look at your three examples:
[17,1..171] == []. Since you specify 17,1, Haskell sees that the first two elements of your list ought to be seventeen and one, so you must be counting by -16. In that case, Haskell wants to stop as soon as the elements are smaller than the last element---but they start that way, and so no elements are produced. To count up by one, you want [17,18..171] (the first two elements of your list are 17 and 18), or simply [17..171].
[17, 17..171111] == repeat 17. This one's fun. Since the first two elements of your list are both 17, Haskell determines that you must be counting up by zero—and it will happily keep counting up until the result exceeds 171111. Of course, when counting by zero, this will never happen, and so you get an infinite list of seventeens. To count up by seventeen, you want [17,34..171111], or [17,17+17..171111] if you think that's clearer.
take 54 [171,234..] vs. take 54 [171,244..]. I'm not sure what behavior you were expecting here, but what they're each doing is the same as above: the first returns a list of fifty-four integers, starting at 171 and counting by 234 - 171 = 63; the second returns a list of fifty-four integers, starting at 171 and counting by 244 - 171 = 73. Each list goes on infinitely far (or at least until maxBound, if the lists are of finite Ints and not arbitrarily-large Integers), and so you just request the first fifty-four elements.
For some of the more nitty-gritty details on what range syntax means (it's translated into functions in the Enum type class), including slightly surprising behavior on ranges of floating-point numbers, hammar has a good answer to another question.
Well, the semantics of those operations are a little bit different than you expect. The construct [a,b..c] is actually just syntactical sugar for enumFromThenTo a b c, which behaves a little bit like this:
Calculate d = b - a. The output of [a,b..c] is [a,a+d,a+d+d,a+d+d+d,...]. This is repeated, till a+n*d > c, if d and c - a have different signs (In this case, the list would be infinite, so there is no output instead), or till maxBound or minBound is reached, then the output ends. (Of course, this is implemented differently, since we are using arbitrary instances of Enum here).
So [1,3..10] becomes [1,3,5,7,9] and since 17 - 17 = 0, [17, 17..171111] yields [17,17+0,17+0+0...]. And by that slightly complicated rule, [17, 1..171] yields the empty list.
To your addition: [x,y..] is implemented using the function enumFromThen x y, that behaves just like enumFromThenTo, except that there is no boundary condition, so if your Enum is infinite, so will be the resulting list.
I, too, was a bit surprised by this behavior, so I wrote a range function that feels more natural to me (and maybe to you as well):
range step start end = takeWhile (<=end) $ iterate (+step) start
Citing your examples:
Count by 17's from one to 171
is done by range 17 1 171, producing [1,18,35,52,69,86,103,120,137,154,171]
Count by 17's from seventeen to 1711111
is done by range 17 17 1711111, producing [17,34,51,68,85, ...
I was also confused by this tutorial: The tutorial uses the word step, which isn't explained, and in my view isn't what I think of as a step. It then shows the example which can easily be misinterpreted. since [2,4..20] looks like it means with a step 2 starting at 4.
The clue is in the output though:
ghci> [2,4..20]
[2,4,6,8,10,12,14,16,18,20]
if you look carefully (which I didn't). It means start at 2, the next being 4, with implicit step thenceforth of (4 - 2), carry on to output numbers in steps of 2 up to at most 20.
"ghci>" [1,6..20]
[1,6,11,16]
Note 20 is not output as 16 + 5 is greater than 20

Resources