There are a lot of integer values in my application, which are used as Map keys. I want to wrap them into new types to make program more type safe, though these Int values are used for indexing arrays too.
So I have to unwrap newtypes to ints with arrays.
I haven’t found a class for such purpose, but it seems pretty common need now.
class ArrayIndex i where
at :: forall a. Array a -> i -> Maybe a
infixl 8 index as !!!
instance arrayIndexInt :: ArrayIndex Int where
at = (!!)
newtype SomeInt = SomeInt Int
derive instance Newtype SomeInt _
at :: forall a i. Newtype i Int => Array a -> i -> Maybe a
at = coerce Array.(!!)
It will work so long as the newtype has a Newtype instance and the constructor is exported. If not, then defining a type class like that is likely the next best solution. But, it should generally only be defined in application code, not library code.
I don’t think a Newtype instance is actually required for this. coerce is from Safe.Coerce.Coercible, which is automatically solved as long as the constructor is exported.