Haskell中的强制与约束同一性

Haskell中的强制与约束同一性,haskell,Haskell,强制没有关于约束的默认标识,这有什么原因吗 导入数据。强制 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 新类型Id a=Id a a::Id Int a=强制3--不好 --•无法将类型“a0”的表示与使用“强制”产生的“Int”表示相匹配 --•由文字“3”产生的不明确

强制
没有关于约束的默认标识,这有什么原因吗


导入数据。强制
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
新类型Id a=Id a
a::Id Int
a=强制3--不好
--•无法将类型“a0”的表示与使用“强制”产生的“Int”表示相匹配
--•由文字“3”产生的不明确类型变量“a0”
--阻止解决约束“(Num a0)”。
--可能的修复:使用类型注释指定“a0”应该是什么。
--这些潜在的例子存在:
--实例Num Integer--在“GHC.Num”中定义
--实例Num Double--在“GHC.Float”中定义
--实例Num Float--在“GHC.Float”中定义
b::Id Int
b=强制(3::Int)

我想象它可以尝试用
a0~Int
(或一般的其他约束)来解决这个问题,因为身份(和合并约束)似乎总是一个选项

,下面的代码本质上是模糊的

a :: Id Int
a = coerce 3
因为它实际上意味着

a :: Id Int
a = coerce (fromInteger (3 :: Integer))
这里
fromInteger
可以返回类
Num
中的任何类型
T
,只要
T
可以通过
强制转换为
Id Int

当然,一种可能的解决方案是
T~Int
,但这不是唯一的解决方案。考虑这个设计实例:

newtype T = T Int

instance Num T where
   fromInteger n = T (fromInteger n + 1)

a :: Id Int
a = coerce (3 :: T)
-- which means  a = coerce (fromInteger (3 :: Integer) :: T)
这里,我们有
a=ID4
,因为
fromInteger
增加了
Int
,这不同于
ID3
我们将从
a=concure(3::Int)
得到的


当对
强制3
执行类型推断时,Haskell无法知道我们的意思是
强制(3::Int)
还是
强制(3::T)
,因此代码本身就是模糊的,因此会被拒绝。

如果我正确理解这个问题,我认为答案可能是令人厌烦的:没有人有这个想法,也没有时间去做工程工作,把这个特例添加到类型检查器中。我看不出有什么技术上的理由不这样做,如果你每次都发出警告(或隐藏在语言扩展后面,或两者兼而有之),我认为GHC HQ很可能会接受这样的补丁。

谢谢。我想知道我是否对正在发生的事情有错误的理解。这似乎是个好项目。我不确定我能不能做到,我应该把它贴到GHC的gitlab上,以防有人有兴趣去拿它。@DanielWagner那将是一个特例:我们将解决与其他人不同的
强制
约束。我们已经有了“特殊”类(数字默认值),还需要更多吗?如果程序员打算使用
强制(3::T)
但忘记了
::T
,该怎么办?如果我们有可强制a X,可强制b Y,可强制a b
,有可强制到
Y的
X
,会怎么样;我们得到的是
a~b~X
还是
a~b~Y
?也许在这种情况下,魔法不应该触发,并且仍然会产生歧义错误。我并不强烈反对魔法,但不知何故我害怕不可预知的魔法。不可预知的魔法肯定是最糟糕的,违约是危险的。(例如,我没有考虑到
Int
Integer
之间的区别)。我可以想象,基于“失败后重试”的解决方案可能会触发一些不可预见的循环(?)。也就是说,可强制存在于可信的代码库中。这个问题可以(我认为)以一种超越可强制的方式来界定:如果我们把那些类型类(和类型…)看作是一个逻辑系统,它实际上是关于一些关系被其他关系商化。注:我想我们会得到所有这些关系的自反传递闭包。我认为,这是一种不需要实际商类的商的方法,通过饱和同一类中不同元素的关系。它可能是如何实现的。我认为,
Typeable
会产生很多这样的约束