如何实现不定式数据结构以便在F#中获取按需项目

时间:2015-08-06 17:42:57

标签: f#

我需要在图表中用以下字母表命名节点。 当我创建一个新节点(按需)时,我只需要从这组字符中获取第一个未使用的字母。

在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或类似的东西,但不知道如何以功能方式连接各个部分

2 个答案:

答案 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()永远不会是无论如何功能;)

警告

这是线程安全,所以如果你需要这个,请在​​内部函数中使用锁