Hello,
I've been playing with gleam recently. And in particular I've been making a simple system for restricting the values of a type, and making some generic union types.
Restricted types
Since Gleam has a nice type system I was wondering whether it would be possible to restrict the input of a function by a "Restricted type". For example one could restrict a float to be non zero, or to satisfy other property.
I got something that seems to be working so far, and I was wondering whether the gleam community would be interested. It would look like this:
fn my_func(x: Restricted(Float, NonZero)){
x
}
where Restricted has been defined as
pub type Restricted(type_, property) {
Restricted(val: type_, prop: property)
}
And NonZero is the following opaque type that act is here to specify the property the value needs to satisfy
pub opaque type NonZero {
NonZero
}
The user can create a Restricted(Float, NonZero) value (actually a Result containing it) using the following function (which has been defined for the NonZero property),
pub fn non_zero_from_float(x: Float) {
case x {
0.0 -> Error("Cannot created an instance with the input x=0")
_ -> Ok(Restricted(x, NonZero))
}
}
Generic tagged unions
While doing this I needed to use a tagged union. Of course one can just use custom types to do this, and one should do this in most cases, but in few cases I think it is handy to have a "generic tagged union", in particular for type that were already defined in gleam or in another package. So I started to define generic unions , and it would look like this:
fn increment(x:Union2(Int, Float))->Union2(Int, Float){
case x{
Int(n) -> U2Type1(n+1)
Float(y) -> U2Type2(y +. 1.)
}
}
It could be nice that, when we need such quick unions, we all used the same syntax, ie all use the same types and variants.
So I was wondering what's your opinion on this kind of things.