SML中的函数类型

时间:2011-02-12 10:40:19

标签: sml currying

任何人都可以向我解释为什么下面给出的函数类型是
('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

2 个答案:

答案 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)

xxs构成了(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有三个参数:

  1. 适用范围的功能。
  2. 累加器的初始值。
  3. 折叠范围。
  4. 假设累加器的类型为'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
    

    报道的是什么。