Ocaml 为什么有必要使用“;rec";
我定义了以下函数,它计算两个数的最大公约数Ocaml 为什么有必要使用“;rec";,ocaml,Ocaml,我定义了以下函数,它计算两个数的最大公约数 let rec gcd n m = if m = 0 then n else gcd m (n mod m);; 如果没有关键字rec,它将无法工作 我很好奇,为什么需要有rec 在作用域中没有其他名为gcd的函数,因此编译器必须调用什么就很清楚了 即使作用域中有另一个函数gcd,编译器也可以尝试按某种顺序进行匹配,并查看适合的函数,如Haskell中的函数 你能举个例子说明为什么这很有用吗?大多数函数都是非递归函数,因此,默认情况下,函数名在函数体
let rec gcd n m = if m = 0 then n else gcd m (n mod m);;
如果没有关键字rec
,它将无法工作
我很好奇,为什么需要有rec
在作用域中没有其他名为gcd
的函数,因此编译器必须调用什么就很清楚了
即使作用域中有另一个函数gcd
,编译器也可以尝试按某种顺序进行匹配,并查看适合的函数,如Haskell中的函数
你能举个例子说明为什么这很有用吗?大多数函数都是非递归函数,因此,默认情况下,函数名在函数体中不可见是合理的。这也有助于重新定义函数,假设您有模块
User
和name
函数,并且希望在新模块中重新定义它:
module User = struct
type t = {name : string}
let name t = t.name
end
module RespectedUser = struct
include User
let name t = "Mr. " ^ name user
end
如果
name
name(在本例中,函数名的选择是多么糟糕)在主体中可见,那么实现name
函数就会困难得多。它会更多地阻碍我们,然后才是真正需要的。在Haskell中编程时,当您意外地使函数递归时,这始终是我的一个问题,尽管您只是想重载现有函数。大多数函数都是非递归的,因此,默认情况下,函数名在其主体中不可见是合理的。这也有助于重新定义函数,假设您有模块User
和name
函数,并且希望在新模块中重新定义它:
module User = struct
type t = {name : string}
let name t = t.name
end
module RespectedUser = struct
include User
let name t = "Mr. " ^ name user
end
如果
name
name(在本例中,函数名的选择是多么糟糕)在主体中可见,那么实现name
函数就会困难得多。它会更多地阻碍我们,然后才是真正需要的。在Haskell中编程时,当您意外地使函数递归时,这对我来说总是一个问题,尽管您只是想重载现有函数。是否rec
表示您希望它执行TCO?如果是这种情况,就像Scala的递归注释一样,如果不能优化递归,它会警告您。@Carcigenicate:No,rec
对于任何递归函数定义都是必需的。是否可能是的一半重复?它是关于F#,但显然它们的根是相似的。rec
的可能重复是否表示您希望它执行TCO?如果是这种情况,就像Scala的递归注释一样,如果不能优化递归,它会警告您。@Carcigenicate:No,rec
对于任何递归函数定义都是必需的。是否可能是的一半重复?它是关于F#,但显然它们的根是相似的。Haskell和OCaml的可能副本都不支持重载。你用name
的定义替换了旧的定义。我的意思是覆盖(通常混淆这两个词)。OCaml支持方法重载,因为方法具有后期绑定。重载是指如果您有两个同名的函数,但参数的数量或类型不同,并且编译器根据您使用的参数调用正确的函数。重写是指子类定义的方法与超类型具有相同的签名,并且在运行时根据接收方的类型选择正确的版本。OCaml不支持前者。它确实支持后者。你所做的都不是。不,只是检查了术语,我是对的。这叫做重载。使用新方法重载作用域中的现有名称时。最重要的是当你将同一个变量反弹到新名称时。(前面的答案是对我的第二条评论的评论,它与你的评论同时出现)。好吧,我们从不同的语言中挑选术语,到目前为止术语还没有固定下来。我对重载有不同的定义。也许,重新绑定名称会更好。你同意吗?Haskell和OCaml都不支持重载。你用name
的定义替换了旧的定义。我的意思是覆盖(通常混淆这两个词)。OCaml支持方法重载,因为方法具有后期绑定。重载是指如果您有两个同名的函数,但参数的数量或类型不同,并且编译器根据您使用的参数调用正确的函数。重写是指子类定义的方法与超类型具有相同的签名,并且在运行时根据接收方的类型选择正确的版本。OCaml不支持前者。它确实支持后者。你所做的都不是。不,只是检查了术语,我是对的。这叫做重载。使用新方法重载作用域中的现有名称时。最重要的是当你将同一个变量反弹到新名称时。(前面的答案是对我的第二条评论的评论,它与你的评论同时出现)。好吧,我们从不同的语言中挑选术语,到目前为止术语还没有固定下来。我对重载有不同的定义。也许,重新绑定名称会更好。你同意吗?