简体   繁体   中英

F# Seq.next - what's the correct pattern?

As part of a project that uses the Strategy Pattern, I'm trying to write a function, that creates a function, which returns the next value of an infinite sequence each time it is applied. At the moment I am doing it using this dodgy GetNext function:

let GetNext<'T> (enumerator:System.Collections.Generic.IEnumerator<'T>) =
    let n = enumerator.MoveNext()
    enumerator.Current

let FunctionFactory<'T> =
    let s = 0.0 |> Seq.unfold (fun i -> Some(i, if 0.0 = i then 1.0 else 0.0))
    let enumerator = s.GetEnumerator()
    (fun (ignoredParam:'T) -> GetNext enumerator )

I would like FunctionFactory to look like this:

let FunctionFactory<'T> =
    let s = 0.0 |> Seq.unfold (fun i -> Some(i, if 0.0 = i then 1.0 else 0.0))
    (fun (ignoredParam:'T) -> Seq.next s )

The ignoredParam is used in other functions that pass through the same strategy pattern and depend on the context it provides. Since this looks so bad, really I have two questions. Why isn't there a Seq.next ? What is the correct/elegant way of implementing a wide variety of sequence expressions that can be injected into a strategy framework like this?

Edited following Fyodor Soikin's answer - Sequence expressions appeal to me at the moment because they help me to think about the problems I'm looking at. Rather than mutable imperative style code, I'd like to build on this pattern with more complex input sequences.

Have you noticed that you never dispose of the enumerator? This is why there is no Seq.next : its usage would require unsound design.

As for the second question, it is not entirely clear what is "this" that you're trying to implement. As far as I can glean from the code, you're trying to produce a "stateful procedure" that will yield 1.0 or 0.0, switching every time it is called. Right?

If so, I would do it via a mutable value. A lot less overhead than a sequence:

let FunctionFactory<'T> =
    let mutable flag = true
    fun (_:'T) -> 
       flag <- not flag
       if flag then 1.0 else 0.0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM