haskell - 是否可以在自定义类型和标准库类型之间建立强制实例?

标签 haskell deriving coerce derivingvia

举个简单的例子,假设我想要一个类型来表示井字游戏标记:

data Mark = Nought | Cross
Bool 相同
Prelude> :info Bool
data Bool = False | True    -- Defined in ‘GHC.Types’
但是没有Coercible Bool Mark他们之间,即使我导入 GHC.Types (我首先认为 GHC 可能需要 Bool 的定义位置可见),拥有此实例的唯一方法似乎是通过 newtype .
或许我可以定义 newtype Mark = Mark Bool并定义 NoughtCross对于双向模式,我希望有比这更简单的东西。

最佳答案

不幸的是,你运气不好。作为documentation for Data.Coerce explains , “可以假设存在以下三种实例:”

  • 自我实例,如 instance Coercible a a ,
  • 用于在表示或幻像类型参数不同的数据类型的两个版本之间进行强制的实例,如 instance Coercible a a' => Coercible (Maybe a) (Maybe a') , 和
  • 新类型之间的实例。

  • 此外,“尝试手动声明 Coercible 的实例是一个错误”,这就是你所得到的。任意不同的数据类型之间没有实例,即使它们看起来相似。

    这可能看起来令人沮丧,但考虑一下:如果有一个 Coercible Bool 之间的实例和 Mark ,是什么阻止它强制 NoughtTrueCrossFalse ?可能是BoolMark在内存中以相同的方式表示,但不能保证它们在语义上足够相似以保证 Coercible实例。

    您使用新类型和模式同义词的解决方案是解决问题的一种很好、安全的方法,即使它有点烦人。
    另一种选择是考虑使用 Generic .例如,查看 genericCoerce 的想法来自 this other question

    关于haskell - 是否可以在自定义类型和标准库类型之间建立强制实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66309171/

    相关文章:

    Haskell 类型化实例

    haskell - 从记录中的字段派生实例

    wpf - 强制传播值(value)

    r - 从列表转换为数字

    具有与其 C 对应物相同的强制表示的 Haskell 类型?

    haskell - 通过散列实现排序

    haskell - 以下函数是否存在标准名称?

    haskell - 新线 haskell

    haskell - `DeriveAnyClass` 和空实例有什么区别?

    haskell - 运行相同的 haskell 应用程序需要不同的时间