[Haskell-beginners] No accumulation of partially applied functions allowed?
byorgey at seas.upenn.edu
Tue Jun 26 22:59:29 CEST 2012
On Tue, Jun 26, 2012 at 10:08:49PM +0200, Obscaenvs wrote:
> Sorry if this is a less than stellar question.
> The problem:
> Given a function f :: a -> a -> a -> b, make it work on a list
> instead: f `applyTo`[x,y,z] where [x,y,z] :: [a].
> My stab at a general solution was
> applyTo f  = error "no arg"
> applyTo f (x:xs) = go (f x) xs
> go acc  = acc
> go acc (y:) = acc y
> go acc (y:ys) = go (acc $ y) ys
> I thought this would work, functions being "first class citizens" but
> ghci complains:
> "Occurs check: cannot construct the infinite type: t1 = t0 -> t1
> In the return type of a call of `acc'
> Probable cause: `acc' is applied to too many arguments
> In the expression: acc y
> In an equation for `go': go acc (y : ) = acc y"
> The 'probable cause' isn't the real cause here, but something to do
> with the fact that it's impossible to accumulate functions in this
> Or am I just too tired too make it work? I can see that the type of
> `go` could be a problem, but is it insurmountable?
The type of `go` is exactly the problem. In particular, the type of
acc's first parameter. In the third clause of go's definition, we can
see that `acc` and (acc $ y) are both used as the first argument to
go, hence they must have the same type. However, this is impossible
-- if acc has type (t0 -> t1), then y must have type t0, and (acc $ y)
has type t1, so it would have to be the case that t1 = t0 -> t1 --
hence the error message.
It is not possible in Haskell to define `applyTo`.* I know this
function gets used a lot in lisp/scheme, but Haskell style is
different. If you explain the context in which you wanted this
function, perhaps we can help you figure out a better way to structure
things so it is not needed.
* At least not without crazy type class hackery.
More information about the Beginners