【问题标题】:Curried function defined in terms of its own partial application根据自己的部分应用定义的柯里化函数
【发布时间】:2022-08-14 02:02:51
【问题描述】:

以下 SML 代码取自华盛顿大学 course 的家庭作业。 (具体来说,它是提供的代码的一部分,以便学生可以使用它来完成course webpage 上列出的作业 3。)我不是在这里寻求家庭作业帮助——我想我明白代码在说什么。我不太明白的是如何允许根据自己的部分应用程序定义柯里化函数。

 datatype pattern = 
     WildcardP
   | VariableP of string
   | UnitP
   | ConstantP of int
   | ConstructorP of string * pattern
   | TupleP of pattern list

fun g f1 f2 p =
  let 
    val r = g f1 f2      (* Why does this not cause an infinite loop? *)
  in
    case p of
        WildcardP         => f1 ()
      | VariableP x       => f2 x
      | ConstructorP(_,p) => r p
      | TupleP ps         => List.foldl (fn (p,i) => (r p) + i) 0 ps
      | _                 => 0
  end

函数绑定是一个递归定义,它利用pattern 的数据类型绑定中的递归结构。但是当我们到达val r = g f1 f2 行时,为什么不会导致执行认为,“等等,g f1 f2 是什么?这就是我通过将f2 传递给由将f1传递给g。那么让我们回到g\"的定义,进入一个无限循环?

    标签: functional-programming sml currying partial-application


    【解决方案1】:

    函数g 永远不会以f1f2 以外的任何值递归调用。按理说,g f1 f2 无论被调用多少次,都会得到相同的结果。

    我建议阅读https://smlhelp.github.io/book/ 柯里化部分的Staging 部分。

    一个更简单、更简单的例子,展示了同样的事情。一个人为的函数,它对 int 进行计数,直到提供的函数返回 true。

    fun x (f: int -> bool) (a: int) : int =
      let 
        val g = x f
      in
        if a = 0 then 0
        else if f a then a
        else g (a - 1)  
      end
    

    我们也可以看到将其转换为 OCaml 也是如此。

    let rec x f a =
      let g = x f in
      if a = 0 then 0
      else if f a then a
      else g (a - 1)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-14
      • 2012-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-22
      • 1970-01-01
      • 2018-02-05
      相关资源
      最近更新 更多