在函数式编程中确定函数的类型

时间:2012-03-30 13:04:58

标签: types definition

下面的等式是用Miranda语法编写的,但由于Miranda和Haskell之间的相似性,我希望Haskell程序员能够理解它!

如果您定义以下功能:

rc v g i = g (v:i)
rn x = x
rh g = hd (g [])


f [] y = y 
f (x:xs) y = f xs (rc x y)

g [] y = y
g (x:xs) y = g xs (x:y)

你如何计算出函数的类型?我想我理解如何解决f,g和rn,但我对部分应用程序部分感到困惑。

将会是* - > * 或其他任何内容 - >任何内容,我认为它是 - > Haskell中的&a;

对于f和g,函数类型 [*] - > * - > *

我不确定如何找到rc和rh的类型。在rc中,g被部分地应用于变量i - 所以我猜这会将i的类型约束为[*]。 rc和g在rc的定义中应用了什么顺序?是否将g应用于i,然后将结果函数用作rc的参数?或者rc是否采用v,g和i的3个独立参数?我真的很困惑..任何帮助将不胜感激!谢谢你们。

抱歉忘了添加hd是列表的标准head函数,定义为:

hd :: [*] -> *
hd (a:x) = a
hd [] = error "hd []"

2 个答案:

答案 0 :(得分:6)

从已知的类型以及定义中如何使用表达式推断出类型。

让我们从顶部开始,

rc v g i = g (v : i)

所以rc :: a -> b -> c -> d我们必须看到有关a, b, cd的信息。在右侧,显示(v : i),因此对于v :: a,我们会看到i :: [a]c = [a]。然后g应用于v : i,所以g :: [a] -> d完全适用于<{p}}

rc :: a -> ([a] -> d) -> [a] -> d

rn x = x表示rn的参数类型没有约束,其返回类型相同,rn :: a -> a

rh g = hd (g [])

由于rh的参数g已应用于RHS上的空列表,因此它必须包含[a] -> b类型,可能有关a或{{1}的更多信息跟随。实际上,b是RHS上g []的参数,因此hdg [] :: [c],因此

g :: [a] -> [c]

下一步

rh :: ([a] -> [c]) -> c

第一个参数是一个列表,如果是空的,则结果是第二个参数,因此f [] y = y f (x:xs) y = f xs (rc x y) 跟随第一个等式。现在,在第二个等式中,在RHS上,f :: [a] -> b -> b的第二个参数是f,因此rc x y必须与rc x y具有相同的类型,我们称之为y 1}}。但

b

,所以rc :: a -> ([a] -> d) -> [a] -> d 。因此

b = [a] -> d

最后

f :: [a] -> ([a] -> d) -> [a] -> d

从第一个等式推导出g [] y = y g (x:xs) y = g xs (x:y) 。从第二个开始,我们推导出g :: [a] -> b -> b,因为我们将b = [a]的第一个参数作为头,并将其限制在第二个参数中,因此

g

答案 1 :(得分:6)

我将使用haskell语法来编写类型。

rc v g i = g (v:i)

此处rc有三个参数,因此其类型类似于a -> b -> c -> dv:i必须是与vi相同类型的元素列表,因此v :: ai :: [a]g已应用于该列表,因此g :: [a] -> d。 如果你把所有这些放在一起,你会得到rc :: a -> ([a] -> d) -> [a] -> d

正如您已经发现rn :: a -> a,因为它只是身份。

我不知道您在hd中使用的rh函数的类型,所以我会跳过它。

f [] y = y 
f (x:xs) y = f xs (rc x y)

此处f有两个参数,因此其类型类似于a -> b -> c。 从第一种情况开始,我们可以推导出b == c,因为我们返回y,并且第一个参数是一个列表。 现在我们知道f :: [a'] -> b -> b。 在第二种情况下,请注意x的输入中yrc是如何给出的:y必须是函数[a'] -> drc x y :: a' -> d(它必须也是y的类型,因为它作为f的第二个参数传递。 最后,我们可以说f :: [a'] -> ([a'] -> d) -> ([a'] -> d)。由于->是右关联的,因此相当于[a'] -> ([a'] -> d) -> [a'] -> d

你可以用同样的方式推断其余的。