Seq голова и хвост - PullRequest
       2

Seq голова и хвост

3 голосов
/ 10 января 2011

Существует ли однострочный способ реализации nextLine?

let s = ref seqOfLines
let nextLine() =
  let hd = Seq.head !s
  s := Seq.skip 1 !s
  hd

seqOfLines предполагается бесконечным

Ответы [ 3 ]

4 голосов
/ 10 января 2011

Один из способов сделать это - использовать базовый IEnumerator<String>.Это не совсем одна строка, но кажется, что она немного чище, чем ваша реализация.(Не зависит от mutable, правильно использует идиомы .NET.)

По сути, вы получаете интерфейс IEnumerator <'a> из последовательности, а затем просто зацикливаетесь на вызове MoveNext.Это будет нормально работать с бесконечной последовательностью.

> let getNextFunc (seqOfLines : seq<'a>) =               
-     let linesIE : IEnumerator<'a> = seqOfLines.GetEnumerator()
-     (fun () -> ignore (linesIE.MoveNext()); linesIE.Current);;

val getNextFunc : seq<'a> -> (unit -> 'a)

Чтобы использовать, просто передайте getNextFunc последовательность, и она вернет вашу функцию nextLine.

> let sequenceOfStrings = seq { for i = 0 to 10000 do yield i.ToString() };;

val sequenceOfStrings : seq<string>

> let nextLine = getNextFunc sequenceOfStrings;;  

val nextLine : (unit -> string)

> nextLine();;
val it : string = "0"
> nextLine();;
val it : string = "1"
> nextLine();;
val it : string = "2"
> nextLine();;
val it : string = "3"
2 голосов
/ 10 января 2011

Хммм, я думаю, что вы пытаетесь подойти к этому слишком настойчиво, и в результате вы в конечном итоге напишете какой-нибудь прикольный код и потеряете преимущества программирования функций.

Вы могли бы выигратьпереписав вашу функцию так, чтобы она заняла current state и вернула value * next state.Это сохранит вашу функцию чисто функциональной.Вам также может оказаться проще преобразовать ваш бесконечный seq в LazyList вместо этого (для этого вам нужно сослаться на F # PowerPack), поэтому вам не нужно напрямую прикасаться к базовому перечислителю:

> open LazyList
let seqOfLines = Seq.initInfinite (fun i -> i) |> LazyList.ofSeq
let nextLine = function Cons(x, xs) -> x, xs | Nil -> failwith "Empty list";;

val seqOfLines : LazyList<int>
val nextLine : LazyList<'a> -> 'a * LazyList<'a>

> nextLine seqOfLines;;
val it : int * LazyList<int> = (0, seq [1; 2; 3; 4; ...])
> nextLine (snd it);;
val it : int * LazyList<int> = (1, seq [2; 3; 4; 5; ...])
> nextLine (snd it);;
val it : int * LazyList<int> = (2, seq [3; 4; 5; 6; ...])
> nextLine (snd it);;
val it : int * LazyList<int> = (3, seq [4; 5; 6; 7; ...])
0 голосов
/ 28 января 2017

FSharpx.Collections имеет несколько полезных / эффективных функций, таких как Seq.tail, Seq.Head и Seq.UnCons, которые могут быть полезны, если вы хотите разложить Seq на голову и хвост.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...