让我们假设我有一个Stack
带有一个实例的类型List
:
class Stack a where
push :: a -> Integer -> a
pop :: a -> a
last :: a -> Integer
data List = Empty | Element Integer List
instance Stack List where
push list value = Element value list
pop Empty = error "No elements"
pop (Element _ list) = list
last Empty = error "No elements"
last (Element value _) = value
Run Code Online (Sandbox Code Playgroud)
如何Stack
定义以便List
不限于Integer
价值观?
-- class Stack (?) where ...
data List a = Empty | Element a (List a)
-- instance Show (List a) where ...
Run Code Online (Sandbox Code Playgroud)
考虑使用更高级的类变量.从而:
class Stack s where
push :: s a -> a -> s a
pop :: s a -> s a
last :: s a -> a
data List a = Empty | Element a (List a)
Run Code Online (Sandbox Code Playgroud)
该实例仍然与您编写的完全一样(尽管List
现在已经是实物* -> *
而不是*
):
instance Stack List where
push list value = Element value list
pop Empty = error "No elements"
pop (Element _ list) = list
last Empty = error "No elements"
last (Element value _) = value
Run Code Online (Sandbox Code Playgroud)
这种方法是纯粹的Haskell 2010 - 它不需要扩展.
另外,考虑让你的失败可以观察到; 例如通过改变类型pop
,并last
返回Maybe (s a)
和Maybe a
分别.
在这种情况下,您可以创建一个多参数类:
class Stack a b where
push :: a -> b -> a
pop :: a -> a
last :: a -> b
Run Code Online (Sandbox Code Playgroud)
并定义它:
instance Stack (List b) b where --You don't need to use `b`, but this make it easier to understand
push list value = Element value list
pop Empty = error "No elements"
pop (Element _ list) = list
last Empty = error "No elements"
last (Element value _) = value
Run Code Online (Sandbox Code Playgroud)
请注意,这不是默认(标准化)Haskell功能,您需要将其打开.无论是通过传递-XMultiParamTypeClasses
和-XFlexibleInstances
编译器.
或者你可以写:
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
Run Code Online (Sandbox Code Playgroud)
在源文件的标题中.
需要注意的是可以有几个b
的一a
对,你定义一个实例(反之亦然).这可能使这些类很难使用.比如说你写了一个Dummy
类型:
data Dummy = Dummy
Run Code Online (Sandbox Code Playgroud)
你可以定义:
instance Stack Dummy b where
push x = const x
pop = id
last = const $ error "Dummy object"
Run Code Online (Sandbox Code Playgroud)
现在它意味着你有Stack
可能的每一个实例b
,以便你可以push
和对象的pop
各种东西Dummy
.