SML中函数的类型

SML中函数的类型,sml,currying,Sml,Currying,有人能给我解释一下为什么下面给出的函数类型是 ('a*'b->'b)->'b->'a列表->'b 功能是: fun foldr f b [] = b | foldr f b (x::xs) = f (x, (foldr f b xs)) 当我看这个函数时,我发现类型应该是('a*'b->'b)->'b,因为我们有一个函数f,它接受一个元组,然后在'b返回,而且在基本情况下,我们返回'b,我认为上面的foldr代码是不正确的;应该是 fun foldr f b [] = b |

有人能给我解释一下为什么下面给出的函数类型是
('a*'b->'b)->'b->'a列表->'b

功能是:

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

当我看这个函数时,我发现类型应该是
('a*'b->'b)->'b
,因为我们有一个函数
f
,它接受一个元组,然后在
'b
返回,而且在基本情况下,我们返回
'b
,我认为上面的
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
    

    这就是报告的内容。

    我认为上述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
    

    这就是报告的内容。

    要确定函数的类型,过程基本上如下所示:

    给定一个函数

    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 首先,我们可以看到
    b
    (arg2)与
    foldr
    (return)的返回类型相同,(arg3)是某种未知类型的列表

    f (arg1): 'a b (arg2): 'b (arg3): 'e list (return): 'b
    x
    xs
    组成了(arg3)的列表

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

    f (arg1): 'e * 'b -> 'b b (arg2): 'b (arg3): 'e list (return): 'b x : 'e xs : 'e list 无法进一步简化,因此我们有以下类型:


    foldr:
    ('a*'b->'b)->'b->'a list->'b

    要确定函数的类型,过程基本上如下所示:

    给定一个函数

    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 首先,我们可以看到
    b
    (arg2)与
    foldr
    (return)的返回类型相同,(arg3)是某种未知类型的列表

    f (arg1): 'a b (arg2): 'b (arg3): 'e list (return): 'b
    x
    xs
    组成了(arg3)的列表

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

    f (arg1): 'e * 'b -> 'b b (arg2): 'b (arg3): 'e list (return): 'b x : 'e xs : 'e list 无法进一步简化,因此我们有以下类型:


    foldr:
    ('a*'b->'b)->'b->'a list->'b

    非常感谢您的解释。非常感谢您的解释。您的
    foldr
    版本是错误的。当您编写
    f
    函数以获取其参数时,我无法理解如何得出类型的正确结论。如果仍然有疑问,那么您可以使用@Jesper.Reenberg进行检查-我的印象是,这个问题是关于自定义foldr实现的,而不是标准的foldr实现。这不正确吗?您的
    foldr
    版本是错误的。当您编写
    f
    函数以获取其参数时,我无法理解如何得出类型的正确结论。如果仍然有疑问,那么您可以使用@Jesper.Reenberg进行检查-我的印象是,这个问题是关于自定义foldr实现的,而不是标准的foldr实现。这是不对的吗?