简体   繁体   English

Haskell不安全将新类型强制转换为相同的新类型

[英]Haskell unsafeCoerce newtype to identical newtype

Imagine there is a newtype declaration: 想象有一个新类型声明:

newtype T = T Int

This declaration is in a module but not exported. 此声明在模块中,但未导出。 I would like to pass a value of type T to a function. 我想将T类型的值传递给函数。 Now, I can declare my own version of T using the exact same definition. 现在,我可以使用完全相同的定义声明自己的T版本。 The compiler will of course complain if I pass (my.T 0) to a function expecting (hidden.T 0) . 如果我将(my.T 0)传递给期望(hidden.T 0)的函数,编译器当然会抱怨。 I will use unsafeCoerce to coerce the former to the latter. 我将使用unsafeCoerce将前者强制为后者。 It's mentioned here that usage is safe "between a newtype and the type that it wraps." 这里提到,使用“在新类型和它包装的类型之间”是安全的。 I would like to just check if it's also safe in the case I described. 我只想检查一下我描述的情况是否也安全。

I know this is frowned upon and against all principles of good software practices, type theory, functional programming philosophy, ghc policies, common sense,..etc. 我知道这与良好软件规范,类型理论,功能编程哲学,ghc策略,常识等所有原则背道而驰。 Yet, I want to know if this will "normally" work. 但是,我想知道这是否“正常”起作用。

This might be safe with the current GHC implementation, but this is not the recommended way to solve your particular problem. 在当前的GHC实施中,这可能是安全的,但这不是解决特定问题的推荐方法。

The pattern that is usually used instead is to have an internal module like this: 通常使用的模式是具有一个内部模块,如下所示:

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

newtype T = T Int

This module is declared as un-exported in your Cabal file. 在您的Cabal文件中,此模块声明为未导出。 Then, in the module where you want to use the type in, you import the Types module, and use the constructor directly: 然后,在要使用Types模块中,导入Types模块,并直接使用构造函数:

module Foo.Bla where

import Foo.Types (T(..))

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

Finally, you can export the opaque type however you want. 最后,您可以根据需要导出不透明类型。 For example: 例如:

module Foo (T) where

import Foo.Types (T(..))

makeT :: Int -> T
makeT = T

It is possible to use coercion instead, but it would be a bad idea to rely on it. 可以改用强制,但是依靠它是一个坏主意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM