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

问题描述 投票:1回答:1

我应该如何键入和实现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

haskell variadic-functions
1个回答
2
投票

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

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

相反,它更容易使用

data Run a = Run { run :: a }

所以f1f2不再拥有相同的类型。

如果您只关心函数Int -> ... -> Int,可能会有一些使用类型族,GADT,DataKinds等的解决方案。但这可能有点过分,取决于你想要实现的目标。

© www.soinside.com 2019 - 2024. All rights reserved.