什么 . (点)代表什么?
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]:它有两个函数f
和g
,对于一个值x
,它会returnf (g x)
.在数学中,这表示为 f ∘ g:它产生一个函数,该函数首先应用 g,然后应用 f 对 g.
的结果
在这种特定情况下,它将首先应用 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
则相反。他们到底是怎么做到的,这些类型没有说明;但他们确实提供了正在发生的事情的大纲。
.
(点)代表什么?例如它在 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]:它有两个函数f
和g
,对于一个值x
,它会returnf (g x)
.在数学中,这表示为 f ∘ g:它产生一个函数,该函数首先应用 g,然后应用 f 对 g.
在这种特定情况下,它将首先应用 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
则相反。他们到底是怎么做到的,这些类型没有说明;但他们确实提供了正在发生的事情的大纲。