Nick
Nick

Reputation: 697

Haskell : Dots in function

Can someone please tell me why in this function are used "." ?

     longestProductLen :: [(Barcode, Item)] -> Int
     longestProductLen = maximum . map (length . fst . snd)

Upvotes: 1

Views: 336

Answers (3)

Landei
Landei

Reputation: 54584

The other answers are good, but for easier reading, you can mentally just add a variable on both sides of the equation and replace the . by a $ or parens, so your example would read:

longestProductLen xs = maximum $ map (\y -> length $ fst $ snd y) xs

For reference: The original version is called "pointfree style" ("points" are not the dots but variables).

Upvotes: 1

AndrewC
AndrewC

Reputation: 32455

longestProductLen :: [(Barcode, Item)] -> Int
longestProductLen = maximum . map (length . fst . snd)

. is function composition, so maximum. map f means map f, then take the maximum, so for example if f is (+5), then we get

  ( maximum .map (+5) ) [1,2,3,4] 
= maximum (map (+5) [1,2,3,4])
= maximum [6,7,8,9]
= 9

In the code you gave, . is also used in (length . fst . snd).

Notice that since longestProductLen :: [(Barcode, Item)] -> Int, if we're mapping f over that list, f has to accept data of type (Barcode, Item).

It takes snd, which gives it an item, then fst, so it must be that type Item = (Product,???). I don't know what ??? is but it doesn't matter for your function. I'll guess Double.

Next we take length, so type Product = [????]. I suspect it's [Char], i.e. String, but no matter, we can take it's length.

So let's work that through on some sample data:

  (length . fst . snd) ("|| ||| | ||| | || |||| | |", ("Gruyere",1.05))
= (length . fst)  (snd ("|| ||| | ||| | || |||| | |", ("Gruyere",1.05)) )
= (length . fst) ("Gruyere",1.05)
= length ( fst ("Gruyere",1.05) )
= length "Gruyere"
= 7

Putting it together gives

  longestProductLen [("|| ||| | ||| | || |||| | |", ("Gruyere",1.05)),
                     ("| ||| || ||| ||  |||| || |", ("Emmental",0,97)),
                     ("||||| ||| ||| ||  | || |||", ("Gouda",1,21))]
= maximum . map (length . fst . snd) 
                    [("|| ||| | ||| | || |||| | |", ("Gruyere",1.05)),
                     ("| ||| || ||| ||  |||| || |", ("Emmental",0,97)),
                     ("||||| ||| ||| ||  | || |||", ("Gouda",1,21))]
= maximum [7,8,5]
= 8

So we've found that the longest product length was 8 (from Emmental).

Upvotes: 6

Karolis Juodelė
Karolis Juodelė

Reputation: 3771

. is function composition. It can be defined as

(.) :: (b->c) -> (a->b) -> a -> c
f . g = \x -> f (g x)

Upvotes: 4

Related Questions