Skip to content

Instantly share code, notes, and snippets.

@baronfel
Last active May 9, 2022 16:33
Show Gist options
  • Save baronfel/88074c9d4b919ec5a5f1a10747328d38 to your computer and use it in GitHub Desktop.
Save baronfel/88074c9d4b919ec5a5f1a10747328d38 to your computer and use it in GitHub Desktop.
// here's the machinery
/// an SRTP function call that can call any type with a Count member, regardless of the return type of the Count
let inline count (t: ^t): ^u =
(^t : (member Count : ^u) (t))
/// an SRTP function call that can call any Indexer on a type, regardless of the input and output of that indexer
let inline item (t: ^t) (x: ^u) : ^v =
(^t : (member get_Item: ^u -> ^v) (t, x))
module Seq =
/// a function that can enumerate over any type with a Count member of type int and an Item indexer that takes an int
let inline ofGenericItem t=
seq {
for x in 0 .. (count t - 1) do
yield item t x
}
// here's a custom type
type MyThing (length: int) =
member x.Count = length
member x.Item with get (c) =
if c < length then
c
else
failwith "boom"
// here's using it
let m = MyThing(3)
let numbers = Seq.ofGenericItem m
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment