2

again another question generated by my attempts at the Project Euler questions (follow on from a previous question). I'm having trouble understanding the following line:

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

Specifically

map (product . take 13) (tails number)

The type signature for the first argument of map from ghci is [c] -> c:

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

The type signature for map (product . take 13) from ghci is [[b]] -> [b]:

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

Am I right in saying that as the first argument of map should be a function, [[b]] is not referring to a list of lists, but rather to a list of (partially applied) functions generated by (product . take 13), with the second argument for the partial functions coming from (tails number)?

4

2 回答 2

3

Here is a point-free version:

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

let's make this a bit more obvious:

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

so as you can see - it first gets the final-segments of the numbers-list (this is a list again)

then it uses map to get the product for each of these segments (again a list)

and finaly it searches for the maximum of those products and returns it

PS: I striped the print in both versions - I think the IO will just complicate matters and it's not really important ... you can always print it out afterwards ;)

于 2014-08-17T13:29:48.023 回答
1

Am I right in saying that as the first argument of map should be a function ?

Yes, the first argument of map should be a function. See it's type:

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

It takes a function of type (a -> b). But in your case the a -> b refers to (product . take 13):

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

So, this is a function which takes a list of elements [a] and produces a single value of type a from it. You can actually test this in ghci:

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

For simplicity, it gets applied like this:

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

the second argument for the partial functions coming from (tails number)?

tails is a normal function with the type:

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

So, this function accepts a list of element and gives you a list of list of elements. You can play with this around in ghci:

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

I hope that makes it clear.

于 2014-08-17T13:46:38.440 回答