任何人都可以向我解释为什么下面给出的函数类型是
('a * 'b -> 'b) -> 'b -> 'a list -> 'b
?
功能是:
fun foldr f b [] = b
| foldr f b (x::xs) = f (x, (foldr f b xs))
当我查看这个函数时,我发现类型应该只是('a * 'b -> 'b) -> 'b
,因为我们有一个函数f
,它接受一个元组,只返回'b
并且也在基本情况我们返回'b
。
答案 0 :(得分:4)
要确定函数的类型,过程基本上是这样的:
给定一个函数,
fun foldr f b [] = b
| foldr f b (x::xs) = f (x, (foldr f b xs))
假设所有类型的参数和返回值都是未知的。
foldr : 'a -> 'b -> 'c -> 'd f (arg1): 'a b (arg2): 'b (arg3): 'c (return): 'd
fun foldr f b [] = b
首先,我们可以看到b
(arg2)与foldr
(返回)的返回类型相同,而(arg3)是某种未知类型的列表。
f (arg1): 'a b (arg2): 'b (arg3): 'e list (return): 'b
| foldr f b (x::xs)
x
和xs
构成了(arg3)的列表。
f (arg1): 'a b (arg2): 'b (arg3): 'e list (return): 'b x : 'e xs : 'e list
= f (x, (foldr f b xs))
然后f
(arg1)是一个函数,它接受一个2元组并返回与foldr
相同的类型返回(返回)。元组的第一项是x
的相同类型。元组的第二项与返回类型foldr
(返回)的类型相同。到目前为止,类型也适用于递归调用foldr
。
f (arg1): 'e * 'b -> 'b b (arg2): 'b (arg3): 'e list (return): 'b x : 'e xs : 'e list
fun foldr f b [] = b
| foldr f b (x::xs) = f (x, (foldr f b xs))
它不能再简化,所以我们有类型:
foldr:('a * 'b -> 'b) -> 'b -> 'a list -> 'b
答案 1 :(得分:1)
我认为foldr
的上述代码不正确;它应该是
fun foldr f b [] = b
| foldr f b (x::xs) = (f x (foldr f b xs))
也就是说,它不应该传入一个参数元组,而是像往常一样传递累加器和递归调用foldr
作为参数。
至于类型的来源,请记住foldr
有三个参数:
假设累加器的类型为'b
,列表的类型为'blist
。我们知道函数的整体返回类型应该是'b
,因为我们有
fun foldr f b [] = b
现在让我们看看f
的类型。我们有这个:
foldr f b (x::xs) = (f x (foldr f b xs))
这将获取列表的第一个元素和累加器,然后生成必须为'b
类型的内容。该列表的类型为'a list
,累加器的类型为'b
,因此该函数的类型为('a * 'b -> 'b)
。
总结一下,函数的类型是
('a * 'b -> 'b) -> 'b -> 'a list -> 'b
报道的是什么。