Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In F#, how to get head/tail of a seq without re-evaluating the seq

Tags:

f#

I'm reading a file and I want to do something with the first line, and something else with all the other lines

let lines = System.IO.File.ReadLines "filename.txt" |> Seq.map (fun r -> r.Trim())

let head = Seq.head lines
let tail = Seq.tail lines

```

Problem: the call to tail fails because the TextReader is closed. What it means is that the Seq is evaluated twice: once to get the head once to get the tail.

How can I get the firstLine and the lastLines, while keeping a Seq and without reevaluating the Seq ?

the signature could be, for example :

let fn: ('a -> Seq<'a> -> b) -> Seq<'a> -> b
like image 627
Molochdaa Avatar asked Aug 17 '18 17:08

Molochdaa


People also ask

What is 1 C equal to in Fahrenheit?

Answer: 1° Celsius is equivalent to 33.8° Fahrenheit.

What is 15ºc into ºF?

Answer: 15° Celsius is equal to 59° Fahrenheit.

Whats is in Fahrenheit?

Definition: The Fahrenheit (symbol: °F) is a unit of temperature that was widely used prior to metrication. It is currently defined by two fixed points: the temperature at which water freezes, 32°F, and the boiling point of water, 212°F, both at sea level and standard atmospheric pressure.


1 Answers

The easiest thing to do is probably just using Seq.cache to wrap your lines sequence:

let lines =
  System.IO.File.ReadLines "filename.txt"
  |> Seq.map (fun r -> r.Trim())
  |> Seq.cache

Of note from the documentation:

This result sequence will have the same elements as the input sequence. The result can be enumerated multiple times. The input sequence is enumerated at most once and only as far as is necessary. Caching a sequence is typically useful when repeatedly evaluating items in the original sequence is computationally expensive or if iterating the sequence causes side-effects that the user does not want to be repeated multiple times.

like image 106
Wesley Wiser Avatar answered Sep 26 '22 16:09

Wesley Wiser