Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting all function arguments in haskel as list

Tags:

haskell

Is there a way in haskell to get all function arguments as a list.

Let's supose we have the following program, where we want to add the two smaller numbers and then subtract the largest. Suppose, we can't change the function definition of foo :: Int -> Int -> Int -> Int. Is there a way to get all function arguments as a list, other than constructing a new list and add all arguments as an element of said list? More importantly, is there a general way of doing this independent of the number of arguments?

Example:

module Foo where
    import Data.List

    foo :: Int -> Int -> Int -> Int
    foo a b c = result!!0 + result!!1 - result!!2 where result = sort ([a, b, c])
like image 267
wawa Avatar asked Sep 05 '25 03:09

wawa


1 Answers

is there a general way of doing this independent of the number of arguments?

Not really; at least it's not worth it. First off, this entire idea isn't very useful because lists are homogeneous: all elements must have the same type, so it only works for the rather unusual special case of functions which only take arguments of a single type.

Even then, the problem is that “number of arguments” isn't really a sensible concept in Haskell, because as Willem Van Onsem commented, all functions really only have one argument (further arguments are actually only given to the result of the first application, which has again function type).

That said, at least for a single argument- and final-result type, it is quite easy to pack any number of arguments into a list:

{-# LANGUAGE FlexibleInstances         #-}

class UsingList f where
  usingList :: ([Int] -> Int) -> f

instance UsingList Int where
  usingList f = f []

instance UsingList r => UsingList (Int -> r) where
  usingList f a = usingList (f . (a:))

foo :: Int -> Int -> Int -> Int
foo = usingList $ (\[α,β,γ] -> α + β - γ) . sort

It's also possible to make this work for any type of the arguments, using type families or a multi-param type class. What's not so simple though is to write it once and for all with variable type of the final result. The reason being, that would also have to handle a function as the type of final result. But then, that could also be intepreted as “we still need to add one more argument to the list”!

like image 196
leftaroundabout Avatar answered Sep 07 '25 20:09

leftaroundabout