gpt4 book ai didi

f# - 范围分配

转载 作者:行者123 更新时间:2023-12-01 07:53:01 25 4
gpt4 key购买 nike

我仍在尝试获得函数式编程的心态,因此我不确定这个问题是否有意义:是 scoping assignment在 F# 中可能与在 R 中一样吗?

假设我正在设计一个函数 split xx = y + 10z对于 abs(int:y) <= 5abs(int:z) .

 let split x =
let z = abs(x / 10)
let modz = abs(x % 10)
let y =
if modz > 5 then
let z = z + 1
abs(5 - modz)

else
modz
(y, z);;

给定一个大于 5 的 z 模块,我想修改 z 的值。
即,对于 split 27我期望结果为 (2, 3)。
split 22;;
val it : int * int = (2, 2)

split 27;;
val it : int * int = (2, 2)

最佳答案

let关键字创建一个名称绑定(bind),这意味着“这个名称意味着这个值”(或这个函数)。它是不可变的:在您编写的代码中,名称 zsplit函数将始终引用值 abs(x / 10) ,并且无法更改。 let z = z + 1您的 if modz > 5 = ... 中的表达式 block 没有重新分配外部 z 的值.相反,它正在创建一个 z的定义,它所在的 block 的本地。你写的代码是说“在这个 if 表达式的真实部分,我想要一个名为 z 的名称,它的值是我的 z 的值目前知道,加1。哦,对我隐藏“外部”z:在这个 block 内,我想使用我对z的定义。”但在街区之外,“外部”z不变。这允许您随意重新定义名称,而不会意外导致其他代码中的错误,这通常是一件好事。

您要做的是创建一个可变变量,这是通过添加 mutable 来完成的。关键字到 let .为可变变量分配新值的语法也不同:它不使用 let一点也不。你想要的是写:

let mutable z = abs(x / 10)
// Later on...
z <- z + 1

左向箭头运算符 <-意思是“改变这个可变变量的值”。如果你写 z = z + 1 ,这是一个常见的新手错误,编译器会警告你这是一个被忽略的 bool 值——因为当它不是 let 的一部分时绑定(bind), =运算符是比较。表达式 z = z + 1在问“ z 是否等于 z + 1?”这将永远是错误的(除非您创建了一个非常奇怪的数字类型)。

我真的不推荐使用 mutable作为基本规则。尝试重写你的逻辑以避免它。例如,您可以这样编写函数:
let split x =
let z = abs(x / 10)
let modz = abs(x % 10)
let increment = if modz > 5 then 1 else 0
let y = if modz > 5 then abs(5 - modz) else modz
(y, z + increment)

那会更实用,并且避免使用 mutable .

关于f# - 范围分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40215583/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com