在类型类

时间:2016-02-27 00:19:20

标签: haskell generics types automata

我对类型类有一个奇怪的问题。所以你可以定义一个基本类型类:

class Property x where
    checkThing :: x -> Int -> Bool
    transformThing :: x -> x

如果您想拥有一个包含多个参数的类型类,您可以启用:

{-# LANGUAGE MultiParamTypeClasses #-}

这将允许您执行以下操作:

class Property x y where
    checkThing :: x -> Int -> Bool
    transformThing :: x -> y -> Int

这是我的问题:想象一下,我想为自动机(接受语言的那种)编写一个类型类。我会写一个看起来像这样的类型类:

class Automata machine where
    isDeterministic :: machine -> Bool
    acceptsInput :: machine -> String -> Bool

自动机接受输入并确定该输入是否是语言的一部分。上述课程适用于此。但等待这个仅限于字符列表(String)如果我想通过Automata进行推广呢?好吧,我可以在我的类定义中添加另一个变量:

class Automata machine alphabet where
    isDeterministic :: machine -> Bool
    acceptsInput :: machine -> [alphabet] -> Bool

嗯,没关系。但字母表可能与机器没有直接关系。我很幸运!我可以启用:

{-# LANGUAGE FunctionalDependencies #-}

强制语言依赖于机器

class Automata machine alphabet | machine -> alphabet where

好的,现在当我创建Automata的实例时,我可以要求字母与机器相关。例如:

instance Automata (FSM alphabet) alphabet where

有效,而且这是正确的

instance Automata (FSM alphabet) othertypevariable where

给出错误。这没关系,但不是很通用。例如,我必须为每种类型的自动机定义一个实例,以及它们可以采用的每种类型的字母表。那太糟了。此外,功能依赖性实际上并不强制关系。你可以写:

 instance Automata (FSM alphabet) Int where

没有编译器错误。这是理想的。

class Automata (machine alphabet) where
    isDeterministic :: machine alphabet -> Bool
    acceptsInput :: machine alphabet -> [alphabet] -> Bool

如果我可以为正在定义的数据实例指定特定的类型参数。例如,可以定义自动机的数据如下所示:

data FSM alphabet = FSM [alphabet]

或类似的东西。这也可以允许定义单个通用实例,例如:

instance Automata (FSM alphabet) where

这些示例是我尝试的简化版本,但此问题的解决方案可以解决我的问题。我怎么能表达这个呢?我可以根据自己的意愿弯曲类型课吗?语言扩展是可以接受的。

1 个答案:

答案 0 :(得分:5)

Haskell类型类可以抽象出任意种类。这意味着参数类型类本身可以有参数。熟悉的示例包括FunctorMonad,它们接受[]Maybe等参数。这是一种用类型*→*类型编写它的方法:

class Automata machine where
    isDeterministic :: machine alphabet -> Bool
    acceptsInput :: machine alphabet -> [alphabet] -> Bool

data FSM alphabet = FSM [alphabet] -- just an example, you need more 
                                   -- stuff to define a real FSM...

instance Automata FSM where 
    ...

使用{-# LANGUAGE KindSignatures #-}可以明确machine种类:

class Automata (machine :: * -> *) where