Reputation: 1220
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
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
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