【问题标题】:Haskell : Dots in functionHaskell:函数中的点
【发布时间】:2012-11-07 22:41:29
【问题描述】:

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

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

【问题讨论】:

  • 使用“m”的原因相同。

标签: haskell max ghci function-composition pointfree


【解决方案1】:
longestProductLen :: [(Barcode, Item)] -> Int
longestProductLen = maximum . map (length . fst . snd)

.是函数组合,所以maximum. map f表示映射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)。

【讨论】:

    【解决方案2】:

    . 是函数组合。可以定义为

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-01-31
        • 2011-08-03
        • 1970-01-01
        • 1970-01-01
        • 2019-08-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多