如何修复"非法数据类型上下文"(使用-XDatatypeContexts)?

use*_*558 3 haskell

我是Haskell的新学习者,我的代码如下:

data Num a=>Units a = Units a (SymbolicManip a )

      deriving (Eq)
Run Code Online (Sandbox Code Playgroud)

我不确定如何修复它?

有人可以帮帮我吗?

chi*_*chi 16

数据类型中的类型类上下文现在被认为是一个不太有用的特性.问题是以下内容无法编译:

foo :: Units a -> a
foo (Units x _) = x+x
Run Code Online (Sandbox Code Playgroud)

这应该直观地编译,因为Units a参数只能为a满足的类型构造Num a.因此,在销毁(模式匹配)时,应该能够访问Num a实例.然而事实并非如此,并且Num a必须在销毁方面提供违反直觉的规定:

foo :: Num a => Units a -> a
foo (Units x _) = x+x
Run Code Online (Sandbox Code Playgroud)

因此,标准建议是Num aUnits a数据类型声明中删除约束,并将其添加到每个涉及的函数中Units a.

另一种选择是启用GADT并将数据类型更改为:

data Units a where
   Units :: Num a => a -> SymbolicManip a -> Units a
Run Code Online (Sandbox Code Playgroud)

这做了"正确"的事情:构造一个值Num a需要一个实例,而是在销毁时提供.通过这种方式,上面的第一个声明将是良好的类型.foo


我几乎忘记了"快速和脏"选项,即启用过时的数据类型上下文功能:这是通过在文件的开头添加行来完成的

{-# LANGUAGE DatatypeContexts #-}
Run Code Online (Sandbox Code Playgroud)

不过,我宁愿修改代码而不是启用此语言扩展.