Применение функции к произвольно длинному списку аргументов - PullRequest
2 голосов
/ 10 мая 2010

Я хочу создать функцию apply, которая принимает функцию с произвольным количеством аргументов, а также список целых чисел и возвращает результат функции (где каждое целое число в списке является аргументом по порядку.

Я думал что-то вроде:

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

Но я знаю, что это не сработает, потому что сигнатура типа неправильная - функция не принимает список значений, она просто принимает некоторое количество аргументов типа int.

Кроме того, когда я добираюсь до базового случая, аргумент f для применения должен фактически быть целым числом, так или иначе нарушая сигнатуру типа.

Кто-нибудь знает, как бороться с такого рода проблемами?

Ответы [ 2 ]

11 голосов
/ 10 мая 2010

Я хочу создать функцию apply, которая принимает функцию с произвольным количеством аргументов, а также список целых чисел,

Почему ты хочешь это сделать? Возможно, ваша структура аргумента должна быть передана как структура данных, но пока вы слишком ограничили проблему, чтобы убедиться, что она не приведет к идиоматическому решению Haskell.

7 голосов
/ 10 мая 2010

Вы можете сделать это с некоторыми классами причудливого типа

{-# 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]
...