Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Function Haskell是否具有可变函数/元组?_Function_Haskell_Tuples_Currying_Variadic - Fatal编程技术网

Function Haskell是否具有可变函数/元组?

Function Haskell是否具有可变函数/元组?,function,haskell,tuples,currying,variadic,Function,Haskell,Tuples,Currying,Variadic,uncurry函数仅适用于具有两个参数的函数: uncurry :: (a -> b -> c) -> (a, b) -> c 如果我想取消具有任意数量参数的函数,我可以只编写单独的函数: 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

uncurry
函数仅适用于具有两个参数的函数:

uncurry :: (a -> b -> c) -> (a, b) -> c
如果我想取消具有任意数量参数的函数,我可以只编写单独的函数:

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

但这很快就会变得乏味。有没有什么方法可以概括这一点,所以我只需要编写一个函数?

没有简单的方法可以编写一个适用于不同数量参数的
uncurry
的定义

但是,可以使用它生成许多不同的变体,否则您必须手工编写。

从软件包中尝试。与所有形式的重载一样,它是使用类型类实现的。在这种情况下,通过手动拼出最多15个元组的实例就足够了

变量函数也可以使用类型类。这方面的一个例子是。在这种情况下,它是通过对函数类型的结构归纳来完成的。简化后,其工作原理如下:

class Foo t

instance Foo (IO a)
instance Foo b => Foo (a -> b)

foo :: Foo
不难看出,
foo
可以实例化为类型
ioa
a->iob
a->b->ioc
等等。也使用这种技术


但是,结构归纳法对元组不起作用,因为n元组与n+1元组完全无关,所以必须手动拼写实例

我的嗜好之一是想办法用过度紧张的系统技巧来伪装这类东西,所以相信我,我说的结果很难看。特别要注意的是,元组不是递归定义的,所以没有直接抽象元组的真正方法;就Haskell的类型系统而言,每个元组大小都是完全不同的

因此,任何直接使用元组的可行方法都需要生成代码——或者使用TH,或者使用与
tuple
包类似的外部工具

要在不使用生成的代码的情况下伪造它,您必须首先使用递归定义——通常使用带有“nil”值的右嵌套对来标记结束,可以是
(,)
()
或与之等价的东西。您可能会注意到,这与列表的定义类似于
(:)
[]
——事实上,这种递归定义的伪元组可以被视为类型级数据结构(类型列表)或异构列表(例如,HList就是这样工作的)

缺点包括但不限于,实际使用以这种方式构建的东西可能会比它的价值更尴尬,实现类型系统技巧的代码通常令人费解且完全不可移植,最终结果也不一定是等价的-
(a,例如,(b,(c,())
(a,b,c)


如果你想看到它变得多么可怕,你可以看看,尤其是比特。

不是这样,但无论如何,你为什么要这样做?根据我的经验,很少有情况下你需要比比特更多的东西uncurry2@Paul当前位置没有具体的原因,但当我看到任何重复的模式时,我会问自己如何才能概括和分析从中提取。有趣的是,
Data.Tuple.Curry
的源代码提到,不同的实例实际上是由一个单独的程序生成的,然后可能会像手工输入一样粘贴进去。你可以用Daniel Fridlender和Mia Indrika的arity族函数模式编写一个n元
uncurry
zipWithN
的例子在论文《我们需要依赖类型吗?》中给出。“不可能”可能有点粗体。我已将答案改为“不可能”。@Stephentelley该实现是否已在任何地方的包中实现?