Juan Pablo Santos
Juan Pablo Santos

Reputation: 1220

Partially apply function n times

Assume

f x y z = x*y*z

Then I expect to return the application of f three times with each member of the list

foldl ($) f [1,2,3]

Something like (((f 1) 2) 3) = 1*2*3 = 6

The function f would be the accumulator and each iteration of the fold would apply one argument and return a partially applied function as the next accumulator.

Why doesn't this work? Is it because f changes type while iterating?

As an aside: is there any other way to accomplish this type of function application?

Upvotes: 3

Views: 253

Answers (2)

Benjamin Kovach
Benjamin Kovach

Reputation: 3260

In general, you can't do what you're trying to do because the type system distinguishes between functions with different numbers of arguments. What you're trying to do, essentially, is convert a list of values into a list of arguments for a function, which doesn't make sense in context.

However, the instance you're pointing at is literally just foldl (*). If you're performing the same operation on all of the variables in a function, you can just use this (well, you should be using either foldl' or foldr, but you get the idea).

Upvotes: 3

dfeuer
dfeuer

Reputation: 48631

The types look like

foldl :: (a -> b -> a) -> a -> [b] -> a

($) :: (x -> y) -> x -> y

To apply foldl to ($) requires matching (technically, unifying) the type of the first argument to foldl with the type of ($). That is, solving the equation

a -> b -> a  =  (x -> y) -> x -> y

This leads immediately to

a = x -> y
b = x
a = y

Substituting the second and third equations into the first:

a = b -> a

The problem is that Haskell has no type that solves this equation. In particular, it is impossible to write down a solution with a finite number of symbols! It expands first to

a = b -> b -> a

then

a = b -> b -> b -> a

and on forever. So there is no way to choose types for the type variables to make them match, and GHC will complain loudly.

Upvotes: 6

Related Questions