功能组合 - Haskell

时间:2014-08-17 13:17:02

标签: haskell currying function-composition partial-application

我再次尝试项目欧拉问题(follow on from a previous question)时产生的另一个问题。我无法理解以下内容:

print (maximum (map (product . take 13) (tails number)))

具体地

map (product . take 13) (tails number)

来自ghci的map的第一个参数的类型签名是[c] - > C:

ghci> :t (product . take 13)
(product . take 13) :: Num c => [c] -> c

来自ghci的map (product . take 13)的类型签名是[[b]] - >并[b]:

ghci> :t map (product . take 13)
map (product . take 13) :: Num b => [[b]] -> [b]

我是否正确地说,因为map的第一个参数应该是一个函数,[[b]]不是指列表列表,而是指{{1}生成的(部分应用的)函数列表,部分函数的第二个参数来自(product . take 13)

2 个答案:

答案 0 :(得分:3)

这是一个无点版本:

euler8 :: (Ord c, Num c) => [c] -> c
euler8 = maximum . map (product . take 13) . tails

让我们更明显一点:

euler8' numbers = 
  let segments = tails numbers
      groups   = map (take 13) segments -- only take up to 13 numbers from each segment
      products = map product groups
      max      = maximum products
  in max

所以你可以看到 - 它首先得到了数字列表的 final-segments (这又是一个列表)

然后使用map获取每个细分受众群的产品(同样是列表)

并最终搜索这些产品的maximum并将其返回

PS:我在两个版本中划分了print - 我认为IO只会使问题复杂化并且它并不重要......之后你总是可以将它打印出来;)

答案 1 :(得分:1)

  

我是否正确地说,因为地图的第一个参数应该是a   功能?

是的,map的第一个参数应该是一个函数。看到它的类型:

λ> :t map
map :: (a -> b) -> [a] -> [b]

它需要(a -> b)类型的函数。但在您的情况下,a -> b引用(product . take 13)

λ> :t (product . take 13)
(product . take 13) :: Num a => [a] -> a

因此,这是一个函数,它接受元素列表[a]并从中生成一个类型为a的值。你可以在ghci中实际测试这个:

λ> (product . take 14) [1,2,3]
6

为简单起见,它应用如下:

(\x -> product (take 14 x)) [1,2,3]
  

部分函数的第二个参数来自(尾数)?

tails是一个普通函数,类型为:

λ> :t tails
tails :: [a] -> [[a]]

因此,此函数接受元素列表并为您提供元素列表的列表。你可以在ghci中玩这个:

λ> tails [1,2]
[[1,2],[2],[]]

我希望说清楚。