1

谁能告诉我为什么在这个函数中使用“。” ?

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

3 回答 3

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

.是函数组合,所以maximum. map f表示 map f,然后取最大值,例如如果f(+5),那么我们得到

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

在您提供的代码中,.也用于(length . fst . snd).

请注意longestProductLen :: [(Barcode, Item)] -> Int,如果我们f在该列表上进行映射,则因为f必须接受 类型的数据(Barcode, Item)

它需要snd,这给了它一个项目,然后fst,所以它必须是type Item = (Product,???)。我不知道是什么???是,但这对您的功能无关紧要。我猜Double

接下来我们拿length,所以type Product = [????]。我怀疑它是[Char],即字符串,但无论如何,我们可以取它的长度。

因此,让我们通过一些示例数据来解决这个问题:

  (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

把它放在一起给出

  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

所以我们发现最长的产品长度是 8(来自 Emmental)。

于 2012-11-07T23:28:56.530 回答
4

.是功能组合。它可以定义为

(.) :: (b->c) -> (a->b) -> a -> c
f . g = \x -> f (g x)
于 2012-11-07T22:44:02.683 回答
1

其他答案很好,但为了便于阅读,您可以在心理上在等式两侧添加一个变量并.用 a$或 parens 替换,因此您的示例将显示为:

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

供参考:原版称为“ pointfree style ”(“points”不是点而是变量)。

于 2012-11-09T08:45:59.580 回答