## Haskell – 149 – nozioni base sui tipi – 2 Continuo da qui, copio qui.

Tpi polimorfi
Haskell employs a polymorphic type system. This essentially means that you can have type variables, which we have alluded to before. For instance, note that a function like `tail` doesn’t care what the elements in the list are:

``````Prelude> tail [5,6,7,8,9]
[6,7,8,9]
Prelude> tail "hello"
"ello"
Prelude> tail ["the","man","is","happy"]
["man","is","happy"]``````

This is possible because `tail` has a polymorphic type: `[a] -> [a]`. That means it can take as an argument any list and return a value which is a list of the same type.

The same analysis can explain the type of `fst`:

``````Prelude> :t fst
fst :: (a, b) -> a``````

Here, GHCi has made explicit the universal quantification of the type values. That is, it is saying that for all types `a` and `b`, `fst` is a function from `(a,b)` to `a`.

Esercizio
Figure out for yourself, and then verify the types of the following expressions, if they have a type. Also note if the expression is a type error:

``````snd           => (a,b) -> b
null          => errore
head . tail   => [c] -> c

Classi di tipi
We saw last section some strange typing having to do with the number five [post precedente]. Before we delve too deeply into the subject of type classes, let’s take a step back and see some of the motivation.

motivazione
In many languages (C++, Java, etc.), there exists a system of overloading. That is, a function can be written that takes parameters of differing types. For instance, the canonical example is the equality function. If we want to compare two integers, we should use an integer comparison; if we want to compare two floating point numbers, we should use a floating point comparison; if we want to compare two characters, we should use a character comparison. In general, if we want to compare two things which have type `α`, we want to use an `α`−compare. We call `α` a type variable since it is a variable whose value is a type.

Unfortunately, this presents some problems for static type checking, since the type checker doesn’t know which types a certain operation (for instance, equality testing) will be defined for. There are as many solutions to this problem as there are statically typed languages (perhaps a slight exaggeration, but not so much so). The one chosen in Haskell is the system of type classes. Whether this is the “correct” solution or the “best” solution of course depends on your application domain. It is, however, the one we have, so you should learn to love it.

test di uguaglianza
Returning to the issue of equality testing, what we want to be able to do is define a function `==` (the equality operator) which takes two parameters, each of the same type (call it `α`), and returns a boolean. But this function may not be defined for every type; just for some. Thus, we associate this function `==` with a type class, which we call `Eq`. If a specific type `α` belongs to a certain type class (that is, all functions associated with that class are implemented for `α`, we say that `α` is an instance of that class. For instance, `Int` is an instance of `Eq` since equality is defined over integers.

la classe `Num`
In addition to overloading operators like `==`, Haskell has overloaded numeric constants (i.e., 1, 2, 3, etc.). This was done so that when you type in a number like 5, the compiler is free to say 5 is an integer or floating point number as it sees fit. It defines the `Num` class to contain all of these numbers and certain minimal operations over them (addition, for instance). The basic numeric types (`Int`, `Double`) are defined to be instances of `Num`.

We have only skimmed the surface of the power (and complexity) of type classes here. There will be much more discussion of them in Section Classes [prossimamente], but we need some more background before we can get there. Before we do that, we need to talk a little more about functions.

la classe `Show`
Another of the standard classes in Haskell is the `Show` class. Types which are members of the `Show` class have functions which convert values of that type to a string. This function is called `show`. For instance `show` applied to the integer 5 is the string “5”; show applied to the character ‘a’ is the three-character string “‘a’” (the first and last characters are apostrophes). show applied to a string simply puts quotes around it. You can test this in the interpreter:

``````Prelude> show 5
"5"
Prelude> show 'a'
"'a'"
Prelude> show "Hello World"
"\"Hello World\""``````

Note: The reason the backslashes appear in the last line is because the interior quotes are “escaped”, meaning that they are part of the string, not part of the interpreter printing the value. The actual string doesn’t contain the backslashes.

Some types are not instances of `Show`; functions for example. If you try to show a function (like `sqrt`), the compiler or interpreter will give you some cryptic error message, complaining about a missing instance declaration or an illegal class constraint.

👽

Posta un commento o usa questo indirizzo per il trackback.