Haskell unsafe将新类型转换为相同的newtype

ael*_*ndy 5 haskell types type-conversion

想象一下有一个newtype声明:

newtype T = T Int
Run Code Online (Sandbox Code Playgroud)

此声明位于模块中但未导出.我想将类型T的值传递给函数.现在,我可以使用完全相同的定义声明我自己的T版本.如果我传递(my.T 0)给期望的函数,编译器当然会抱怨(hidden.T 0).我将使用unsafeCoerce将前者强迫给后者.这里提到的是"在newtype和它包装的类型之间使用是安全的".我想在我描述的情况下检查它是否也是安全的.

我知道这是对所有良好软件实践,类型理论,函数式编程理念,ghc策略,常识等原则的不满和反对.然而,我想知道这是否"通常"有效.

dfl*_*str 6

对于当前的GHC实现,这可能是安全的,但这不是解决您的特定问题的推荐方法.

通常使用的模式是具有如下内部模块:

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

newtype T = T Int
Run Code Online (Sandbox Code Playgroud)

此模块在Cabal文件中声明为未导出.然后,在要使用类型的Types模块中,导入模块,并直接使用构造函数:

module Foo.Bla where

import Foo.Types (T(..))

f :: T -> Bla
f (T int) = makeBla int
Run Code Online (Sandbox Code Playgroud)

最后,您可以根据需要导出opaque类型.例如:

module Foo (T) where

import Foo.Types (T(..))

makeT :: Int -> T
makeT = T
Run Code Online (Sandbox Code Playgroud)

可以使用强制,但依靠它是一个坏主意.