加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

haskell – 功能依赖中的歧义类型

发布时间:2020-12-14 04:48:58 所属栏目:百科 来源:网络整理
导读:在 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
在 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

然后编译器总是可以告诉(*)的返回类型是什么.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读