2010-05-10 89 views
2

我想创建一个函数apply,它接受一个具有任意数量参数的函数以及一个整数列表,并返回函数的结果(其中每个整数in该列表是为了争论将函数应用于任意长度的参数列表

我的想法是这样的:

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

但我知道这不会起作用,因为该类型签名是不正确的 - 功能并不需要整数的列表。 ,它只需要一些int参数。

此外,当我到达基本情况下,应用的f参数应该实际上是一个整数,无论​​如何都违反了类型签名。

有谁知道如何处理这类问题?

回答

7

你可以用一些奇特的类型类

{-# 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] 
+1

您只需要使用FlexibleInstances,您可以绕过整个IsInt类并直接编写ApplyType(Int - > r)。 – 2010-05-10 17:11:43

11

我想创建一个功能应用是需要与参数的任意数量以及整数列表的功能做到这一点,

你为什么要这样做?也许你的参数结构应该作为一个数据结构来传递,但到目前为止,你已经过度地限制了这个问题,以确保它不会产生一个惯用的Haskell解决方案。