Haskell 有可变参数函数/元组吗? [英] Does Haskell have variadic functions/tuples?

查看:27
本文介绍了Haskell 有可变参数函数/元组吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

uncurry 函数仅适用于接受两个参数的函数:

The uncurry function only works for functions taking two arguments:

uncurry :: (a -> b -> c) -> (a, b) -> c

如果我想对具有任意数量参数的函数进行 uncurry,我可以编写单独的函数:

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?

推荐答案

试试 tuple 包中的 .html#v%3auncurryN">uncurryN.像所有形式的重载一样,它是使用类型类实现的.在这种情况下,通过手动拼出最多 15 个元组的实例,这应该绰绰有余了.

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.

变量函数也可以使用类型类.这方面的一个例子是 Text.Printf.在这种情况下,它是通过对函数类型的结构归纳来完成的.简单来说,它的工作原理是这样的:

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

不难看出 foo 可以被实例化为类型 IO a, a ->;IO b, a ->b->IO c 等等.QuickCheck 也使用这种技术.

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.

不过,结构归纳不适用于元组,因为 n-元组与 n+1-元组完全无关,所以这就是实例具有需要手动拼写.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆