Haskell unsafeCoerce newtype for identical new type

Imagine there is a new type declaration:

newtype T = T Int

This ad is in a module but is not exported. I would like to pass a value of type T to a function. Now I can declare my own version of T using the same definition. Of course, the compiler will complain if I pass the (my.T 0)function to the waiting one (hidden.T 0). I will use unsafeCoerce to force the former to the latter. He mentioned here that use is safe "between the newtype and the type it wraps." I would just like to check if this is safe when I described.

I know this is disapproving and against all the principles of good software practice, type theory, functional programming philosophy, ghc policy, common sense, etc. However, I want to know if this will work “normally”.

+5
source share
1 answer

This may be safe with the current GHC implementation, but this is not the recommended way to solve your specific problem.

Instead of the template, the internal module is usually used:

module Foo.Types (T(..)) where

newtype T = T Int

This module is declared non-exportable in your Cabal file. Then, in the module in which you want to use the type, you import the module Typesand use the constructor directly:

module Foo.Bla where

import Foo.Types (T(..))

f :: T -> Bla
f (T int) = makeBla int

Finally, you can export an opaque type, but you want to. For instance:

module Foo (T) where

import Foo.Types (T(..))

makeT :: Int -> T
makeT = T

Coercion can be used instead, but it would be a bad idea to rely on it.

+6
source

All Articles