Haskell – 9 – elementi fondamentali – 3

Continuo da qui, copio qui, scrollare fino a “Tuples: Combining Different Data Items”.

Tuples: combinare elementi di dati diversi
So far, we have seen how to pass multiple values to a function, but not how a function can return more than one result value. We can achieve this by using tuples:

addMul :: Num a => a -> a -> (a, a)
addMul x y = (x + y, x * y)

A tuple combines multiple components (two integer values, in the above example) into one compound value. The compound value can be manipulated as a single entity and, in particular, be returned as a value from a function.

However, the construction of a compound value is only half of the story. We also need a method for decomposing such values. We achieve this by using a notation dual to that of tuple construction:

fst (x, y) = x
snd (x, y) = y

Note: Both fst and snd are already defined in the Prelude.

In the argument of fst, we do not use a variable to refer to the compound argument as a whole. Instead, we decompose the pair into its components x and y — this is also called decomposition by pattern matching.

Prelude> :l addMul
[1 of 1] Compiling Main             ( addMul.hs, interpreted )
Ok, 1 module loaded.
*Main> addMul 5 6
(11,30)
*Main> fst (addMul 5 6)
11
*Main> snd (addMul 5 6)
30

The combined use of addMul and fst behaves as follows:

fst (addMul 5 6) ⇒  fst (5 + 6,  5 * 6)
                 ⇒  fst (11,  30)
                 ⇒  11

The types of fst and snd. So far, we omitted the type annotations from the definitions of fst and snd. Generally, the Haskell system will automatically infer the types of definitions that lack a signature — however, it is good style to explicitly provide signatures. In all our previous definitions, the type was determined by the operations we applied to the arguments. For example max was restricted to work on types which are members of the type class Ord, since we needed the operator >=, which can only compare certain types of values. The functions fst and snd are different, though. We don’t actually apply any function or operation to x or y, so they could be values of any type. In fact, x and y don’t even have to have the same type. Hence, we can just use type variables to represent the types of x and y without having to add any type class restrictions:

fst :: (a, b) -> a
fst (x, y)  = x

snd :: (a, b) -> b
snd (x, y)  = y

Functions like fst and snd, which can handle arguments of any type are called (parametric) polymorphic functions.

Example: points. Tuples are not just useful to return multiple results, but also for the representation of data items that cannot be modeled by one primitive value alone. A useful example is given by the points in a 2-dimensional Cartesian coordinate system: they can be represented by a pair of integer values. To avoid having to write the less informative (Int, Int) whenever we denote the type of a point, we can introduce a new type name — similar to the introduction of names for repeatedly used values, which we discussed earlier

type Point = (Int, Int)

With this definition, we define some simple operations on points:

-- origin of the coordinate system
--
origin :: Point
origin  = (0, 0)

-- move a given point to the right
--
moveRight :: Point -> Int -> Point
moveRight (x, y) distance  = (x + distance, y)

-- move a given point to upwards
--
moveUp :: Point -> Int -> Point
moveUp (x, y) distance  = (x, y + distance)

Example: colour points. When we extend points to include a colour, another important property of tuples becomes obvious: tuple components may be of different types. Hence, if we denote colour values with a textual (string) representation, we have

-- we represent colours by strings
--
type Colour = String

-- new name for the type of colour points
--
type ColourPoint = (Int, Int, Colour)

which enables the following operations on colour points:

-- origin of the coordinate system in a given colour
--
origin :: Colour -> ColourPoint
origin colour  = (0, 0, colour)

-- move a colour point vertically and horizontally
--
move :: ColourPoint -> Int -> Int -> ColourPoint
move (x, y, colour) xDistance yDistance  
  = (x + xDistance, y + yDistance, colour)

-- compute the distance between two colour points
--
distance :: ColourPoint -> ColourPoint -> Float
distance (x1, y1, colour1) (x2, y2, colour2) 
  = sqrt (fromIntegral (dx * dx + dy * dy))
  where
    dx = x2 - x1
    dy = y2 - y1

Note how we use a where clause in the last definition to avoid repeating the expressions x2 - x1 and y2 - y1. The standard function fromIntegral converts any integral type to any other numeric type. Its signature is

fromIntegral :: (Integral a, Num b) => a -> b

Important symmetries in Haskell. If we compare the syntax of values and types of tuples, we see that they correspond. For example, consider

(10, 15, "green") :: (Int, Int, String)

If we replace the values 10, 15, and "green" with their respective types Int, Int, and String, we obtain the type of the tuple. Moreover, we have a correspondence between term construction and term decomposition (also called pattern matching). Consider,

startPoint = (0, 0, "black")
colourOfPoint (x, y, colour) = colour

If we replace the components in the tuple construction (0, 0, and "black") by variable names (in this case x, y, colour), we arrive at the pattern that can be used to decompose the corresponding tuple.

Nomi speciali per alcune tuples
The following table lists a number of tuple types and their names:

# Expression          	    Name
0 () 	                    Unit
1 n/a 	                    n/a
2 (x_1, x_2) 	            Pair
3 (x_1, x_2, x_3)           Triple
4 (x_1, x_2, x_3, x_4) 	    Quadruple
5 (x_1, x_2, x_3, x_4, x_5) Quintuple
     ⋮ 		
n (x_1,..., x_n)            n-tuple

🤢

Annunci
Post a comment or leave a trackback: Trackback URL.

Trackbacks

Rispondi

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

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. 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 )

Google+ photo

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

Connessione a %s...

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