如何创建一个polyvariadic haskell函数?

我需要一个函数,它接受任意数量的参数(所有相同类型),对它们做一些事情,然后再给出结果。 在我的具体情况下,争议清单是不切实际的。

当我查看haskell库时,我看到函数printf (来自模块Text.Printf )使用类似的技巧。 不幸的是,我无法通过查看源代码来理解这种魔法。

有人可以解释如何实现这个目标,或者至少有一些网页/论文/无论我在哪里可以找到一个好的描述?

动机:

我需要这个的原因非常简单。 对于学校(计算机科学课程),我们需要编写一个能够“记录”数学表达式的模块,将其表达为一个字符串(通过为自己的数据类型编写一个Num / Real / etc实例),并执行对其进行各种操作。

这个数据类型包含一个特殊的变量构造函数,它可以被一个指定函数的值或其他值替换。 其中一个目标是编写一个函数,它使用一些变量(类型对(Char,Rational) )来表达一个表达式,并计算结果。 我们应该看看如何最好地表达功能的目标。 (我的想法:该函数返回另一个函数,该函数与函数中定义的变量一样多的参数 - 似乎是不可能的)。


printf的关键点是能够返回一个String或一个函数。 复制自http://www.haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/src/Text-Printf.html,

printf :: (PrintfType r) => String -> r
printf fmts = spr fmts []

class PrintfType t where
    spr :: String -> [UPrintf] -> t

instance (IsChar c) => PrintfType [c] where
    spr fmts args = map fromChar (uprintf fmts (reverse args))

instance (PrintfArg a, PrintfType r) => PrintfType (a -> r) where
    spr fmts args = a -> spr fmts (toUPrintf a : args)

我们可以提取出的基本结构是

variadicFunction :: VariadicReturnClass r => RequiredArgs -> r
variadicFunction reqArgs = variadicImpl reqArgs mempty

class VariadicReturnClass r where
   variadicImpl :: RequiredArgs -> AccumulatingType -> r

instance VariadicReturnClass ActualReturnType where
   variadicImpl reqArgs acc = constructActualResult reqArgs acc

instance (ArgClass a, VariadicReturnClass r) => VariadicReturnClass (a -> r) where
   variadicImpl reqArgs acc = a -> variadicImpl reqArgs (specialize a `mappend` acc)

例如:

class SumRes r where 
    sumOf :: Integer -> r

instance SumRes Integer where
    sumOf = id

instance (Integral a, SumRes r) => SumRes (a -> r) where
    sumOf x = sumOf . (x +) . toInteger

那么我们可以使用

*Main> sumOf 1 :: Integer
1
*Main> sumOf 1 4 7 10 :: Integer
22
*Main> sumOf 1 4 7 10 0 0  :: Integer
22
*Main> sumOf 1 4 7 10 2 5 8 22 :: Integer
59

许多人告诉你如何创建可变参数函数,但我认为在这种情况下,使用[(Char,Rational)]类型的列表实际上更好。


在关于variadic函数的wiki文章中,引用了这篇文章。 我想这是printf所做的,但我也不明白。 无论如何,这当然是一种矫枉过正,尤其是因为你的论点都是相同的类型。 把它们全部放在一个列表中。 这就是列表的好处 - 同一类型的任意数量的事物。 好吧,它不是很漂亮,但它不会比完整的多变量函数更丑。

链接地址: http://www.djcxy.com/p/43083.html

上一篇: How to create a polyvariadic haskell function?

下一篇: What is polymorphism, what is it for, and how is it used?