我需要在图表中用以下字母表命名节点。 当我创建一个新节点(按需)时,我只需要从这组字符中获取第一个未使用的字母。
在F#中实现这种结构/计算的最佳方法是什么? 请注意,以下字母应按需提取。
假设我有这样的字母的不定式集合(这是重复的字符集合,但忽略它):
let alphabet =
Seq.initInfinite (fun index ->
let alphabet' = "abcdefghijklmnoperstuvxwz"
alphabet'.Chars(index % alphabet'.Length)
)
我特别感兴趣的是跟随语义:
alphabet.next()//生成' a' ......一段时间...... alphabet.next()//生成' b' ......一段时间...... alphabet.next()//生成' c' 等等
我一直在考虑序列,懒惰列表和异步序列,但据我所知,它不符合我的需求。我也不想使用Rx等复杂的库
我怀疑它可以很好地完成懒惰函数,状态monad或类似的东西,但不知道如何以功能方式连接各个部分
答案 0 :(得分:3)
序列可以引用自己,那么这个怎么样?
let alphabet =
let alphabet' = "abcdefghijklmnoperstuvxwz"
let rec loop() = seq {
yield! alphabet'
yield! loop()
}
loop()
alphabet |> Seq.take 100 |> Seq.toList
答案 1 :(得分:2)
实际上你的alphabet
序列非常接近,但是如果你需要拉在 foreach 之类的东西之外,它可能需要额外的开销。< / p>
那么
let pullNext =
let cs = "abcdefghijklmnoperstuvxwz"
let i = ref 0
fun () ->
let c = cs.[!i]
i := (!i + 1) % cs.Length
c
这会给你(我想的)你想要的东西:
> pullNext ();;
val it : char = 'a'
> pullNext();;
val it : char = 'b'
> pullNext();;
val it : char = 'c'
当然这不是纯粹的(并且不会使用太多的monadic魔法)也不是非常功能但是你的alphabet.next()
永远不会是纯无论如何功能;)
这是不线程安全,所以如果你需要这个,请在内部函数中使用锁