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

时间:2012-01-27 16:28:03

标签: haskell types type-conversion

想象一下有一个新类型声明:

newtype T = T Int

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

我知道这是对所有良好软件实践,类型理论,函数式编程理念,ghc策略,常识等原则的不满和反对。然而,我想知道这是否“正常”起作用。

1 个答案:

答案 0 :(得分:6)

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

通常使用的模式是具有这样的内部模块:

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

newtype T = T Int

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

module Foo.Bla where

import Foo.Types (T(..))

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

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

module Foo (T) where

import Foo.Types (T(..))

makeT :: Int -> T
makeT = T

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