tags:

views:

139

answers:

3

I want to create a function apply that takes a function with an arbitrary amount of arguments as well as a list of integers, and returns the result of the function (Where each integer in the list is an argument in order.

I was thinking something like:

apply :: ([Int] -> Int) -> [Int] -> Int
apply f x:xs = apply (f x) xs
apply f [] = f

But I know this won't work because the type signature is wrong - the function doesn't take a list of ints, it just takes some amount of int arguments.

Additionally, when I get to the base case the f argument to apply should actually be an integer, violating the type signature anyway.

Does anyone know how to deal with this sort of problem?

+6  A: 

You can't do this — besides the type being unwritable, how would the program know when you were finished supplying arguments to this hypothetical function? If it takes an arbitrary and unspecified number of Ints, then it takes an infinite number of Ints, because the program can't read your mind to tell which Int should be the last one. Why do you not want to use a list? You even describe it as a "list of arguments" — that seems like precisely the right way to do it.

I'm also not sure what you even imagine it would mean to apply an integer to an integer.

Chuck
+6  A: 

You can do it with some fancy type classes

{-# LANGUAGE FlexibleInstances #-}
-- for ApplyType (Int -> r)

class ApplyType t where
    apply :: t -> [Int] -> Int

instance ApplyType Int where
    apply f _ = f

instance (ApplyType r) => ApplyType (Int -> r) where
    apply f (x:xs) = apply (f x) xs

main :: IO ()
main = do print $ apply ((+) :: Int->Int->Int) [1, 2]
          print $ apply ((\x y z w -> x*y - z`div`w) :: Int->Int->Int->Int->Int) [3,5,8,2]
newacct
You just need FlexibleInstances and you can bypass the whole IsInt class and write ApplyType (Int -> r) directly.
Edward Kmett
+11  A: 

I want to create a function apply that takes a function with an arbitrary amount of arguments as well as a list of integers,

Why do you want to do this? Perhaps your argument structure should be passed as a data structure, but so far you've over constrained the problem to ensure it won't produce an idiomatic Haskell solution.

Don Stewart