gpt4 book ai didi

f# - 重写简单的 C# 嵌套类

转载 作者:行者123 更新时间:2023-12-02 06:44:12 25 4
gpt4 key购买 nike

在 F# 中实现此嵌套类的功能的优雅方法是什么?

  private class Aliaser {
private int _count;
internal Aliaser() { }
internal string GetNextAlias() {
return "t" + (_count++).ToString();
}
}

这是我的第一次尝试,但感觉应该有一个性感的单行:

let aliases = (Seq.initInfinite (sprintf "t%d")).GetEnumerator()

let getNextAlias() =
aliases.MoveNext() |> ignore
aliases.Current

最佳答案

通常的写法是创建一个在闭包中捕获局部状态的函数:

let getNextAlias = 
let count = ref 0
(fun () ->
count := !count + 1;
sprintf "t%d" (!count))

getNextAlias 的类型只是unit -> string,当你重复调用它时,它返回字符串“t1”,“t2”,......这依赖于在可变状态上,但可变状态对用户是隐藏的。

关于你是否可以在没有可变状态的情况下做到这一点——简单的答案是否定的,因为当你用相同的参数调用一个纯函数函数两次时,它必须返回相同的结果。因此,您必须编写具有以下结构的内容:

let alias, state1 = getNextAlias state0
printf "first alias %s" alias
let alias, state2 = getNextAlias state1
printf "second alias %s" alias
// ...

如您所见,您需要保留一些状态并在整个代码中维护它。在 F# 中,处理此问题的标准方法是使用可变状态。在 Haskell 中,您可以使用 State monad,它允许您隐藏状态的传递。使用实现 from this question ,你可以这样写:

let getNextAlias = state { 
let! n = getState
do! setState (n + 1)
return sprintf "t%d" n }

let program =
state {
let! alias1 = getNextAlias()
let! alias2 = getNextAlias()
// ...
}

execute progam 0 // execute with initial state

这与其他计算非常相似,例如 lazyseq,实际上 - state { .. } block 中的计算有一些状态,您可以通过提供状态的初始值来执行它们。但是,除非您有充分的理由需要纯函数式解决方案,否则我更喜欢第一个用于实际 F# 编程的版本。

关于f# - 重写简单的 C# 嵌套类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2869357/

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