什么 . (点)代表什么?

What does . (dot) stand for?

.(点)代表什么?例如它在 sumDigits 中使用,但我不明白它的作用。

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)

.代表Haskell中的function composition

它允许您链接不同的函数。在您的情况下,您可以使用函数组合,而不是执行调用 toDigits 然后调用 sum 的新函数。

sumDigits = sum (map myFunction)

myFunction xs = sum (toDigits xs)

.的定义如下

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

Whosebug 上有一个非常好的示例,您可以查看。

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.

(.) :: (b -> c) -> (a -> b) -> a -> c is function composition [wiki]:它有两个函数fg,对于一个值x,它会returnf (g x) .在数学中,这表示为 f ∘ g:它产生一个函数,该函数首先应用 g,然后应用 fg.

的结果

在这种特定情况下,它将首先应用 map (sum . toDigits),然后再对结果调用 sum。对于映射本身,它将在应用 sum 之前首先调用列表中的每个项目 toDigits。因此它将为数字列表确定数字总和的总和。

(.)是一个中缀运算符。它被定义为

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

因此,

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 ]

应该说清楚了。

但是在任何情况下,您都应该始终将类型签名添加到您的 top-level 定义中。这里有

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

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

这些至少为我们提供了部分文档:toDigits 将整数转换为整数列表,而 sumDigits 则相反。他们到底是怎么做到的,这些类型没有说明;但他们确实提供了正在发生的事情的大纲。