Home > Enterprise >  What does . (dot) stands in haskell?
What does . (dot) stands in haskell?

Time:02-02

For example: I don't understand what does dot stand for in sumDigits

1.

toDigits m = loop m [] where
    loop x y | x <= 0    = y
             | otherwise = loop (x `div` 10) ((x `mod` 10) : y)
sumDigits = sum . map (sum . toDigits)

CodePudding user response:

The . stands for function composition in Haskell.

It allows you to chain different functions. In your case, instead of doing a new function that calls toDigits and then sum over the result, you can use function composition.

sumDigits = sum (map myFunction)

myFunction xs = sum (toDigits xs)

The definition of . is the following.

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

There's a really good example on stackoverflow already you can check.

Say you have these functions:

even :: Int -> Bool
not :: Bool -> Bool

and you want to define your own myOdd :: Int -> Bool function using the two above.

The obvious way to do this is the following:

myOdd :: Int -> Bool myOdd x = not (even x)

But this can be done more succinctly using function composition:

myOdd :: Int -> Bool myOdd = not . even

The myOdd functions behave exactly the same, but the second one is created by "glue-ing" two functions together.

CodePudding user response:

The dot (.) is an infix operator. It is defined so that

(f . g) x = f (g x)

Thus,

sumDigits    =  sum . map (sum . toDigits)
= {- by "eta-expansion" -}
sumDigits xs = (sum . map (sum . toDigits)) xs
             = {- by definition of (.) -}
                sum ( map (sum . toDigits)  xs )
             = {- re-writing as list comprehension -}
                sum [ (sum . toDigits) x | x <- xs ]
             = {- by definition of (.) -}
                sum [ sum ( toDigits x ) | x <- xs ]

which should be clear enough.

But you should always add type signatures to your top-level definitions in any case. Here you have

toDigits :: Integral a => a -> [a]

sumDigits :: Integral c => [c] -> c

These provide at least partial documentation for us: toDigits turns an integral number into a list of integral numbers, and sumDigits goes the other way around. How exactly do they do that, these types do not say; but they do provide a general outline of what's going on.

CodePudding user response:

The (.) :: (b -> c) -> (a -> b) -> a -> c is function composition [wiki]: It takes two functions f and g, and for a value x, it will return f (g x). In mathematics this is denoted as f ∘ g: it produces a function that first applies g and then applies f on the result of g.

In this specific case it will thus first apply map (sum . toDigits) before calling sum on the result. and for the mapping itself it will for each item in the list first call toDigits before applying sum. It will thus for a list of numbers determine the sum of the sum of the digits.

  •  Tags:  
  • Related