[英]Typeclass constraint inside typeclass instance
你好,從Real World Haskell書中做例子,我遇到過這個例子,我無法理解它的含義以及它是如何工作的:
instance Num a=>Num (SymbolicManip a)
在這種情況下,我應該轉換為類似於:“對於類型為SymbolicManip
Num實例,對於其類型a
字段存在約束,即: a
是Num本身的實例”? 有人可以告訴我,如果我解釋正確或解釋?
為什么instance Num (SymbolicManip a)
不夠用?
-- The "operators" that we're going to support
data Op = Plus | Minus | Mul | Div | Pow
deriving (Eq, Show)
{- The core symbolic manipulation type -}
data SymbolicManip a =
Number a -- Simple number, such as 5
| Arith Op (SymbolicManip a) (SymbolicManip a)
deriving (Eq, Show)
{- SymbolicManip will be an instance of Num. Define how the Num
operations are handled over a SymbolicManip. This will implement things
like (+) for SymbolicManip. -}
instance Num a => Num (SymbolicManip a) where
a + b = Arith Plus a b
a - b = Arith Minus a b
a * b = Arith Mul a b
negate a = Arith Mul (Number (-1)) a
abs a = error "abs is unimplemented"
signum _ = error "signum is unimplemented"
fromInteger i = Number (fromInteger i)
PS所有代碼均來自本書( 第 13 章 - 子章節 - 擴展示例 - 數值類型)
地看到,這是重要的SymbolicManip a
不能被實例Num
無a
也作為一個實例Num
所以,就像當我們添加約束的功能,我們可以添加一個約束到一個類型類:
instance Num a => Num (SymbolicManip a) where
-- ^^^^^^^^ "As long as `a` is an instance of `Num`..."
-- ^^^^^^^^^^^^^^^^^^^^^ "...so is `SymbolicManip a`"
我們必須包含Num a =>
約束,因為在實現中,我們使用fromInteger
來生成類型a
成員。 這是不可避免的 ,就像向函數example ab = 2*a + b
添加Num
約束,即example :: Num a => a -> a -> a
。
這是一個更簡單的例子。 考慮這種類型:
newtype Identity a = Identity a
請注意, Identity a
可以是Num
的實例,只要a
也是Num
,因此,我們添加一個約束:
instance Num a => Num (Identity a) where
-- (...)
這意味着如果a
是Num
的實例,則SybolicManip a
也是Num
的實例。
所以如果你有:
x :: SymbolicManip Integer
y :: SymbolicManip Integer
然后你可以編寫x+y
而無需定義它的含義。 但是,如果您嘗試添加兩個SymbolicManip String
值,則會出現類型錯誤,因為String
不是Num
的實例。
如果查看實例,您將看到negate
和fromInteger
都使用Num
功能。 因此,如果您取出約束,那么編譯器會給出關於無法推斷出a
是Num
實例的錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.