类型推理F#-如何生成新的变量



我正试图在f#中开发用于类型推理的算法W,但我想了解如何正确编写生成新变量的函数。

实际上我的功能是

let counter = ref -1
let generate_fresh_variable () : string =
let list_variables = ['a' .. 'z'] |> List.map string
counter.Value <- !counter + 1
list_variables.Item(!counter)

但我对这个解决方案不满意,有人能给我其他更好的想法吗?

如果你真的想用一个不纯的函数来实现这一点,我会这样写:

let mutable counter = -1
let generate_fresh_variable () =
counter <- counter + 1
counter + int 'a'
|> char
|> string

注:

  • 引用单元格已过时。如果您需要杂质,请使用可变变量。(或者,如果您真的想使用引用单元格,更新它的规范方法是使用:=,而不是直接分配给底层Value。(
  • 不需要维护潜在变量名的列表(尤其不需要在每次生成新变量时重新构建整个列表(
  • 如果您需要超过26个变量,会发生什么

如果你想使用一些更复杂的F#技巧,你可以使用序列表达式创建一个名字的inifinte序列(这使得处理循环和处理>26个名字变得非常容易(:

let names = seq {
for i in Seq.initInfinite id do
for c in 'a' .. 'z' do
if i = 0 then yield string c
else yield string c + string i }

获取新名称的函数将从序列中选择下一个名称。您需要使用底层枚举器来完成此操作。另一个不错的技巧是将状态隐藏在局部变量中,并使用lambda:返回函数

let freshName = 
let en = names.GetEnumerator()
fun () -> 
ignore(en.MoveNext())
en.Current

然后根据需要多次拨打freshName()即可。

最新更新