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
head          => [a] -> a
null          => errore
head . tail   => [c] -> c
head . head   => [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.

Trackback

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.

%d blogger hanno fatto clic su Mi Piace per questo: