如何创建包含多元函数的 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
?
由于代码中的 f1
和 f2
具有相同的类型 Run
,因此类型检查器无法区分 run f1
和 run f2
必须具有相同的类型。
这使得难以正确实现可变参数函数。
反而更容易使用
data Run a = Run { run :: a }
这样 f1
和 f2
不再共享同一类型。
如果您只关心函数 Int -> ... -> Int
,可能会有一些使用类型族、GADT、DataKind 等的解决方案。不过,这可能有点矫枉过正,具体取决于您想要实现的目标。
我应该如何输入和实现 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
?
由于代码中的 f1
和 f2
具有相同的类型 Run
,因此类型检查器无法区分 run f1
和 run f2
必须具有相同的类型。
这使得难以正确实现可变参数函数。
反而更容易使用
data Run a = Run { run :: a }
这样 f1
和 f2
不再共享同一类型。
如果您只关心函数 Int -> ... -> Int
,可能会有一些使用类型族、GADT、DataKind 等的解决方案。不过,这可能有点矫枉过正,具体取决于您想要实现的目标。