【问题标题】:Type of a function in SMLSML 中的函数类型
【发布时间】:2011-02-12 19:38:51
【问题描述】:

谁能给我解释一下为什么下面给出的函数类型是
('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.

【问题讨论】:

    标签: sml currying


    【解决方案1】:

    判断一个函数的类型,基本流程是这样的:

    给定一个函数,

    fun foldr f b []      = b
      | foldr f b (x::xs) = f (x, (foldr f b xs))
    

    假设所有类型的参数和返回值都是未知的。

    折叠:'a->'b->'c->'d f (arg1): 'a b (arg2): 'b (arg3): 'c (返回):'d
    fun foldr f b []      = b
    

    首先我们可以看到b(arg2)和foldr(return)的返回类型是一样的,(arg3)是一个未知类型的列表。

    f (arg1): 'a b (arg2): 'b (arg3): 'e 列表 (返回):'b
      | foldr f b (x::xs)
    

    xxs 构成 (arg3) 的列表。

    f (arg1): 'a b (arg2): 'b (arg3): 'e 列表 (返回):'b x:'e xs : 'e 列表
                          = f (x, (foldr f b xs))
    

    然后f (arg1) 是一个函数,它接受一个 2 元组并返回与 foldr 返回 (return) 相同的类型。元组的第一项与x 的类型相同。元组的第二项与foldr的返回类型相同(返回)。到目前为止,这些类型还适用于对 foldr 的递归调用。

    f (arg1): 'e * 'b -> 'b b (arg2): 'b (arg3): 'e 列表 (返回):'b x:'e xs : 'e 列表
    fun foldr f b []      = b
      | foldr f b (x::xs) = f (x, (foldr f b xs))
    

    它不能被进一步简化,所以我们有类型:

    文件夹:('a * 'b -> 'b) -> 'b -> 'a list -> 'b

    【讨论】:

    • 非常感谢您的解释,它确实有帮助。
    【解决方案2】:

    我认为foldr 的上述代码不正确;应该是

    fun  foldr f b [] = b 
       | foldr f b (x::xs) = (f x (foldr f b xs))
    

    也就是说,它不应该传入参数元组,而是像往常一样传入累加器和对foldr 的递归调用。

    至于类型来自哪里,记住foldr接受了三个参数:

    1. 在范围内应用的函数。
    2. 累加器的初始值。
    3. 折叠的范围。

    假设累加器的类型为'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
    

    报告的内容是什么。

    【讨论】:

    • 您对foldr 的版本有误。当您编写 f 函数以对其参数进行柯里化时,您如何得出正确的类型结论让我感到震惊。如果仍有疑问,您可以联系definition
    • @Jesper.Reenberg- 我的印象是这个问题是关于自定义 foldr 实现,而不是标准 foldr 实现。这是不正确的吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-07
    • 2013-01-16
    • 2016-03-19
    • 2019-11-28
    • 2021-02-15
    相关资源
    最近更新 更多