类型中的多个类型参数?

Cub*_*i73 9 haskell typeclass

让我们假设我有一个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)

Dan*_*ner 9

考虑使用更高级的类变量.从而:

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分别.


Wil*_*sem 7

在这种情况下,您可以创建一个多参数类:

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.