如何创建包含多元函数的 Haskell 数据结构?

How to create a Haskell data structure containing polyvariadic functions?

我应该如何输入和实现 run,以便下面的语句起作用?

data Run = Run {run :: ??}

f1 = Run (\x -> x)
f2 = Run (\x y-> x+y)
f3 = Run (\x y z -> x*(y+z))

print $ run f1 1 :: Int --> 1
print $ run f2 1 2 :: Int --> 3
print $ run f3 1 2 3 :: Int -> 5

运行 中的所有 polyvariadic functions 都是 Int 类型 -> ... -> Int:它们采用可变数量的 Int 参数并产生一个 Int。

如果更简单的话,我可以接受具有最大参数数量的解决方案,例如3:

data Run
  = Run1 (Int -> Int)
  | Run2 (Int -> Int -> Int)
  | Run3 (Int -> Int -> Int -> Int)

f1 = Run1 (\x -> x)
f2 = Run2 (\x y-> x+y)
f3 = Run3 (\x y z -> x*(y+z))

您将如何实施 run

由于代码中的 f1f2 具有相同的类型 Run,因此类型检查器无法区分 run f1run f2必须具有相同的类型。

这使得难以正确实现可变参数函数。

反而更容易使用

data Run a = Run { run :: a }

这样 f1f2 不再共享同一类型。

如果您只关心函数 Int -> ... -> Int,可能会有一些使用类型族、GADT、DataKind 等的解决方案。不过,这可能有点矫枉过正,具体取决于您想要实现的目标。