Haskell有可变参数函数/元组吗? [英] Does Haskell have variadic functions/tuples?
问题描述
uncurry
函数仅适用于带有两个参数的函数: uncurry ::(a - > b - > c) - > (a,b)→> c
如果我想用任意数量的参数解除函数,我可以编写单独的函数:
uncurry2 f(a,b)= fab
uncurry3 f(a,b,c)= fabc
uncurry4 f(a,b,c,d)= fabcd
uncurry5 f(a,b,c,d,e)= fabcde
但这很快就变得乏味。有没有什么办法来推广这个,所以我只需要编写一个函数?
试试uncurryN
来自元组。像所有形式的重载一样,它使用类型类来实现。在这种情况下,通过手动将最多15个元组的实例拼出来,这应该足够了。 使用类型类也可以使用变量函数。其中一个例子是 Text.Printf 。在这种情况下,它是通过对函数类型进行结构归纳来完成的。简化后,它的工作原理如下:
class Foo t
instance Foo(IO a)
instance Foo b => Foo(a - > b)
foo :: Foo
它应该不难看出 foo
可以被实例化为类型 IO a
, a - > IO b
, a - > b - > IO c
等等。 QuickCheck 也使用这种技术。
结构归纳不适用于元组,但是,因为 n -tuple与 n + 1 完全无关> -tuple,所以这就是为什么必须手动拼写出实例的原因。
The uncurry
function only works for functions taking two arguments:
uncurry :: (a -> b -> c) -> (a, b) -> c
If I want to uncurry functions with an arbitrary number of arguments, I could just write separate functions:
uncurry2 f (a, b) = f a b
uncurry3 f (a, b, c) = f a b c
uncurry4 f (a, b, c, d) = f a b c d
uncurry5 f (a, b, c, d, e) = f a b c d e
But this gets tedious quickly. Is there any way to generalize this, so I only have to write one function?
Try uncurryN
from the tuple package. Like all forms of overloading, it's implemented using type classes. In this case by manually spelling out the instances up to 15-tuples, which should be more than enough.
Variadic functions are also possible using type classes. One example of this is Text.Printf. In this case, it's done by structural induction on the function type. Simplified, it works like this:
class Foo t
instance Foo (IO a)
instance Foo b => Foo (a -> b)
foo :: Foo
It shouldn't be hard to see that foo
can be instantiated to the types IO a
, a -> IO b
, a -> b -> IO c
and so on. QuickCheck also uses this technique.
Structural induction won't work on tuples, though, as an n-tuple is completely unrelated to a n+1-tuple, so that's why the instances have to be spelled out manually.
这篇关于Haskell有可变参数函数/元组吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!