在
haskell functonal依赖
wiki:
鉴于这些定义:
data Vector = Vector Int Int deriving (Eq,Show) data Matrix = Matrix Vector Vector deriving (Eq,Show) instance Num Vector where Vector a1 b1 + Vector a2 b2 = Vector (a1+a2) (b1+b2) Vector a1 b1 - Vector a2 b2 = Vector (a1-a2) (b1-b2) {- ... and so on ... -} instance Num Matrix where Matrix a1 b1 + Matrix a2 b2 = Matrix (a1+a2) (b1+b2) Matrix a1 b1 - Matrix a2 b2 = Matrix (a1-a2) (b1-b2) {- ... and so on ... -} class Mult a b c where (*) :: a -> b -> c instance Mult Matrix Matrix Matrix where {- ... -} instance Mult Matrix Vector Vector where {- ... -}
我无法理解为什么有不明确的类型:
m1,m2,m3 :: Matrix (m1 * m2) * m3 -- type error; type of (m1*m2) is ambiguous
显然,当m1和m2是Matrix时,唯一可能的返回类型是Matrix,即应用实例Mult Matrix Matrix Matrix.
解决方法
问题在于类型类声明
class Mult a b c where (*) :: a -> b -> c
通过对两个参数应用(*),您无法确定结果的类型.假设您有两个实例:
instance Mult Int Int Int where ... instance Mult Int Int Integer where ...
然后2 * 4可以是Int类型和Integer类型.
现在你可以争辩说你只有一个实例,所以编译器不应该抱怨.但是Haskell类型的类存在于开放世界中.您始终可以添加更多实例,并且不得在其他地方中断代码.因此,即使您只有一个实例,另一个库中的其他人也可以添加另一个实例.而且,你有两个库,每个都在工作,但却失败了.这显然是一种情感.
请参阅Real World Haskell中的Living in an open world.
因此,通常类型类中函数的返回类型必须可以从其参数派生.这正是函数依赖性的用途.如果你宣布
class Mult a b c | a b -> c where
然后编译器总是可以告诉(*)的返回类型是什么.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。