让我们假设我有一个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.
| 归档时间: |
|
| 查看次数: |
302 次 |
| 最近记录: |