I find myself frequently implementing the same (x, y)
pattern:
let rectangleSizes = seq {
for w = 1 to width do
for h = 1 to height do
yield (w, h)
}
Wouldn't out there be a simple one-liner for this, by chance? Of course I could just write this very same function in just one line, but I feel its readability would suffer quite a bit:
let rectangleSizes = seq { for w = 1 to width do for h = 1 to height do yield (w, h) }
To find the generating function for a sequence means to find a closed form formula for f(x), one that has no ellipses. (for all x less than 1 in absolute value). Problem: Suppose f(x) is the generating function for a and g(x) is the generating function for b.
The type seq<'T> is a type abbreviation for IEnumerable<'T> . This means that any type that implements the generic System. Collections. Generic. IEnumerable<'T> , which includes arrays, lists, sets, and maps in F#, and also most .
seq() function in R Language is used to create a sequence of elements in a Vector.
If I had that initialization all the time I would define my own operator:
let (..) (x0,y0) (xn,yn) =
seq {
for x = x0 to xn do
for y = y0 to yn do
yield (x, y)}
let rectangleSizes = {(1,1) .. (5,7)}
But this shadows the original (..)
operator, however you can use another operator name or a function. Also there is a trick to avoid shadowing the original operator definition.
Alternatively if you use a library which implements Applicative Functors like F#+ you can define it in one single line as:
let rectangleSizes = (fun x y -> (x, y)) <!> {1..width} <*> {1..height}
Note: The function fun x y -> (x, y)
is usually called tuple2
#r @"FsControl.Core.dll"
#r @"FSharpPlus.dll"
open FSharpPlus
let tuple2 a b = (a,b)
let width, height = 5,7
let rectangleSizes = tuple2 <!> {1..width} <*> {1..height}
You could use the fact that 2D arrays implement IEnumerable
, which can be converted to IEnumerable<'T>
(aka seq<'T>
) using Seq.cast
:
let rectangleSizes = Array2D.initBased 1 1 width height (fun w h -> (w, h)) |> Seq.cast<int * int>
Edit: This will create an array that stores all elements though, whereas your initial implementation generates them as needed. If your width and height are big, this may consume too much memory.
You could save a teensy bit of space by :
let rectangleSizes = seq {
for w = 1 to width do
for h = 1 to height -> (w, h)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With