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 -> Booland you want to define your own
myOdd :: Int -> Boolfunction 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 . evenThe 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.
