Reputation: 4292
I want to create an array that can have no more and no less than three elements. Is there a way to do that in a type definition?
Upvotes: 3
Views: 85
Reputation: 817
Building on both @Nghia Bui 's and @glennsl 's answers, you can define your own Triple
type using a tuple of three elements for type safety:
type Triple = Triple of int * int * int
with
static member inline (+) (t1, t2) =
match t1, t2 with
| Triple (a1, a2, a3), Triple (b1, b2, b3) -> Triple (a1 + b1, a2 + b2, a3 + b3)
//add other functionality like map, fold, etc you'd normally expect from Arrays
let t1 = Triple (1, 2, 3)
let t2 = Triple (4, 5, 6)
t1 + t2 //val it : Triple = Triple (5,7,9)
Or you can make it generic:
type GenericTriple<'a> = GenericTriple of 'a * 'a * 'a
with
static member // etc...
Upvotes: 2
Reputation: 3784
Yes, you can:
type Array3<'T> = private Array3 of 'T [] with
member this.Elements = let (Array3 xs) = this in xs
static member Create x y z = Array3 [|x;y;z|]
Now it is ensured that everytime you see a value of type Array3
, the value has exactly three elements:
let myArray = Array3.Create 1 2 3
myArray.Elements |> printfn "%A"
You can read more about this technique in this book.
Upvotes: 3
Reputation: 29106
No, that wouldn't really be an array any longer. You can however create a tuple of three elements:
let triple: int * int * int = (1, 2, 3)
A tuple can also have elements of different types and can be destructured directly instead of through pattern matching since its exact shape is known at compile-time:
let (a, b, c): int * float * string = (1, 2.7, "3")
Upvotes: 6