【发布时间】:2013-12-30 22:32:21
【问题描述】:
我们可以像这样定义函数f和g:
f :: [a] -> [a] -> [a]
f = (++)
g :: [a] -> [a] -> [a]
g = zipWith (+)
f 和 g 都将两个列表作为参数并返回一个新列表,但它们不同:f 返回一个较长的列表,其长度是输入的总和,同时g 处理列表具有相同的长度。如何向 Haskell 弄清楚这一点?
【问题讨论】:
-
实际上
g将具有Num a => [a] -> [a] -> [a]类型,因此它不适用于任意列表,仅适用于数字列表。另外,能否请您澄清一下您的问题? -
@chris 好的,我可以强制
f :: Num a => [a] -> [a] -> [a],所以这两种类型声明没有区别。我的观点是,Haskell 不会同时抱怨f (g [1..10] [11..20]) [21..30]和g (f [1..10] [11..20]) [21..30],但我希望 Haskell 可以对后者给出警告或错误(编译时,而不是运行时)。 -
@SaltyEgg 这需要跟踪类型中的长度参数。可以在 Haskell 中笨拙地做到这一点,但是您对此有一个相当严格的限制,因为只有最现代的 GHC 才具有类型级计算的开始,例如整数加法。您更有可能想要这样做的是 Idris 或 Agda。
-
@chris 认为它是
zipWith (,)。
标签: haskell types type-level-computation