unsafe_cast

Package Version Hex Docs

So, you want to make an integer type that is not zero.

type NonZeroInt = Int

fn main() {
  let n: NonZeroInt = 0
  assert n != 0
}

Type aliases will not protect it.

opaque type NonZeroInt {
  NonZeroInt(inner: Int)
}

fn from_int(i) {
  case i {
    0 -> Error(Nil)
    _ -> Ok(NonZeroInt(i))
  }
}

fn main() {
  let assert Error(Nil) = from_int(0)
  let assert Ok(_) = from_int(1)
}

Yes, out of all the tools we have, opaque types are the right one. Goodbye.

What? You have a weird internal dynamic type situation where the value needs to be the actual value and not a wrapper around the type? Then you do need this library. (look at the bottom example)

There are probably other usecases of changing the type of a value, but using this library for making inline newtypes will be unneeded if/when it becomes an actual language feature:

gleam add unsafe_cast@1
import unsafe_cast

type BinaryInt

fn binary_int_from(int: Int) -> Result(BinaryInt, Nil) {
  case int {
    0 | 1 ->
      Ok(
        unsafe_cast.unsafe_function_that_simply_renames_the_type_of_this_value_to_another_type_and_i_am_sure_that_this_usage_is_safe(
          int,
        ),
      )
    _ -> Error(Nil)
  }
}

fn binary_int_to(bin_int: BinaryInt) -> Int {
  unsafe_cast.unsafe_function_that_simply_renames_the_type_of_this_value_to_another_type_and_i_am_sure_that_this_usage_is_safe(
    bin_int,
  )
}

Further documentation can be found at https://hexdocs.pm/unsafe_cast.

Development

gleam run   # Run the project
gleam test  # Run the tests
Search Document