[英]Ambiguous type in functional dependency
在haskell functonal依賴 維基 :
鑒於這些定義:
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 ,即應用instance 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類型的類存在於開放世界中。 您始終可以添加更多實例,並且不得在其他地方中斷代碼 。 因此,即使您只有一個實例,另一個庫中的其他人也可以添加另一個實例。 而且,你有兩個庫,每個都在工作,但卻失敗了。 這顯然是一種情感。 請參閱真實世界哈斯克爾的開放世界 。
因此,通常類型類中函數的返回類型必須可以從其參數派生。 這正是函數依賴性的用途。 如果你宣布
class Mult a b c | a b -> c where
然后編譯器總是可以告訴(*)
的返回類型是什么。
因為你忘記了所有其他可能性,例如
instance Mult Matrix Matrix Vector where
instance Mult Vector Matrix Vector where
instance Mult Float Matrix Float where
instance Mult Matrix Matrix Float where -- etc.
a :: Vector
a = (m1 >< m2:: Vector) >< m3
b :: Float
b = (m1 >< m2:: Float) >< m3
向類定義添加函數依賴項:
instance Mult a b c | a b -> c
意思是
instance Mult Matrix Matrix Matrix
決定兩個矩陣的問題和那個
instance Mult Matrix Matrix Vector
instance Mult Matrix Matrix Float
被排除在外,因為它們提供了另一種查看“ Matrix
和Matrix
的乘積”的方法。 因此,您發現直觀的事態是您可以通過功能依賴獲得的狀態。
如果功能依賴性是這樣制定的:
instance Mult a b c | b -> a c
這也可以允許你陳述的兩個實例,
instance Mult Matrix Matrix Matrix where
instance Mult Matrix Vector Vector where
但排除我想象的等,它們都具有Matrix
在b
位置(因為它們不得不,由於在ambigous示例m3
作為解釋Matrix
,而不是作為矩陣的乘積的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.