我有以下多PARAM類型類與函數依賴於它們是(載體)混淆類型推斷和函數依賴
module Vec where
class Vec v k | v -> k where -- v is an element of a vector space over k
vZero :: v -- The zero vector in v
vAdd :: v -> v -> v -- Adds two vectors
vSub :: v -> v -> v -- Subtracts two vectors
vMul :: v -> k -> v -- Multiplies a vector by a number from k
infixl 6 |+| -- Shortcut operator for accessing vAdd
(|+|) :: Vec v k => v -> v -> v
(|+|) = vAdd
現在向量空間的元素類型的I加載的代碼段上方插入到ghci
解釋,並要求它向我展示運營商|+|
類型:
*Vec> :t (|+|)
(|+|) :: Vec v k => v -> v -> v
到現在爲止,一切似乎都很正常。但現在我要指定所有數字都是一個特殊的向量空間的元素在自己:
instance Num k => Vec k k where
vZero = 0
vAdd = (+)
vSub = (-)
vMul = (*)
現在奇怪的事情發生了:ghci
不再顯示正確的類型|+|
(儘管它是明確由我指定在上面的代碼):
*Vec> :t (|+|)
(|+|) :: Num v => v -> v -> v
我懷疑這種奇怪的行爲與我使用的FunctionalDependencies
語言的擴展聯繫起來,但我不明白爲什麼ghc
行爲這種方式。我可以看到我自己添加了一個不同的實例Vec v k
其中v
是而不是Num
的一個實例,因此這樣的實例不會與現有實例重疊,從而保留了函數依賴關係。
您可以節省一點的樣板使用[DefaultSignatures](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/type-class-extensions。html#class-default-signatures),並將默認類型定義爲,例如,默認vAdd ::(Num k,v_k)=> k-> k-> k; vAdd =(+)'。然後你可以簡單地寫'instance Vec Int Int;實例Vec Float Float;實例Vec Integer Integer'等,省略了實例的主體。 – user2407038
我不知道是否可以付費使用簡單的新型面膜。 'newtype Self a = Self a'表示數字類型的矢量場透視圖,所以你可以讓'instance Num a => Vec(Self a)a where ...'。 – dfeuer