使用列表的内容作为单个多参数函数的位置参数

2024-04-04

是否有一个标准的 Haskell 函数(或模式)来提取列表的内容并将它们提供给函数,就好像它们是函数的有序位置参数一样?

例如,考虑函数(,)当给定两个位置参数时,将从它们中生成一个二元组:

(,) 3 4 --> (3,4)

假设我有一些我无法更改的外部函数调用给我的参数,表示为列表[3, 4].

是否有“内容”操作,这样就可以工作:

(,) $ contents_of [3, 4]

使得动作contents_of行为就像这些项目被放置在源代码中一样,它们之间有空格作为函数应用程序?

例如,(,) $ contents_of [1]应该是柯里化函数((,) 1)然后又需要一个参数来完成元组的创建。

我的一个想法是尝试将函数折叠到列表上,用折叠函数表达柯里化:

foldr (\x y -> y x) (,) [3, 4]

但看看类型签名foldr:

foldr :: (a -> b -> b) -> b -> [a] -> b

让这看起来很困难。b这里需要是函数类型本身,但是当它被应用于参数时,它不会是具有相同类型签名的函数b太长了,会导致折叠中的类型问题。

这在本质上与 Python 类似*args构造。

我不关心这可能暗示的严格性属性——只关心这样的事情在标准 Haskell 中是否可能。


可以像这样表示 N 元函数:

data FunN r a = FunN Int (a -> FunN r a) | FNil r

然后将普通函数转换为FunN:

f2FunN :: (FunN (a->b) a) -> FunN b a
f2FunN (FNil g)   = FunN 1 (FNil . g)
f2FunN (FunN n g) = FunN (n+1) (f2FunN . g)

然后应用参数列表:

a :: FunN b a -> [a] -> b
a (FNil r)   []    = r
a (FunN _ f) (x:t) = a (f x) t
a _          _     = error "wrong arity"

例如:

Prelude> a (f2FunN $ f2FunN $ FNil (+)) [1,2]
3
Prelude> a (f2FunN $ FNil (+)) [1] 2
3
Prelude> a (f2FunN $ f2FunN $ FNil (+)) [1,2,3]
*** Exception: wrong arity
Prelude> a (f2FunN $ f2FunN $ FNil (+)) [1]
*** Exception: wrong arity

但是当然,您需要在编译时知道函数的数量 - 这样您就知道可以使用该函数包装多少次f2FunN.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用列表的内容作为单个多参数函数的位置参数 的相关文章

随机推荐