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

时间:2018-07-04 08:18:19

标签: haskell variadic-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

Run中所有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

1 个答案:

答案 0 :(得分:2)

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

这使得很难正确实现可变参数功能。

使用起来更容易

data Run a = Run { run :: a }

以便f1f2不再共享同一类型。

如果您只关心函数Int -> ... -> Int,则可能有一些使用类型族,GADT,DataKind等的解决方案。但是,根据您要实现的目标,这可能是过大的。