首页 > 解决方案 > 具有可变参数的函数

问题描述

在 F# 中,不允许函数具有可变参数。但如果我有如下功能:


let f x =
    while x>0 do
      printfn "%d" x
      x <- x-1;;

当我编译这个时,我得到一个编译器错误。(不可变)我将如何修复这个函数?

标签: f#

解决方案


取决于您是希望将最终的变异值x传递回函数的调用者还是仅在本地对其进行变异。

对于仅本地突变,只需声明另一个变量,该变量将是可变的,但最初将具有以下值x

let f x =
    let mutable i = x
    while i>0 do
      printfn "%d" i
      i <- i-1

要将结果传递回调用者,您可以使用参考单元:

let f (x: int ref) =
    while x.Value>0 do
      printfn "%d" x.Value
      x := x.Value - 1

请注意,现在您必须通过.Value属性引用 ref-cell 内容(或者您可以改为使用 operator !,如 in x := !x - 1),并且现在通过:=. 另外,这种函数的使用者现在必须在传递它之前创建一个 ref-cell:

let x = ref 5
f x
printfn "%d" x.Value  // prints "0"

话虽如此,我必须指出,突变通常比纯值更不可靠,更容易出错。在纯函数式编程中编写“循环”的正常方法是通过递归:

let rec f x = 
    if x > 0 then
        printf "%d" x
        f (x-1)

在这里,每次调用f都会再次调用f,其值x减少了1。这将具有与循环相同的效果,但现在没有突变,这意味着更容易调试和测试。


推荐阅读