在类型类中键入变量

447*_*701 0 generics haskell types automata

关于类型类,我有一个奇怪的问题.所以你可以像这样定义一个基本类型:

class Property x where
    checkThing :: x -> Int -> Bool
    transformThing :: x -> x
Run Code Online (Sandbox Code Playgroud)

如果要使用具有多个参数的类型类,可以启用:

{-# LANGUAGE MultiParamTypeClasses #-}
Run Code Online (Sandbox Code Playgroud)

这将让你做以下事情:

class Property x y where
    checkThing :: x -> Int -> Bool
    transformThing :: x -> y -> Int
Run Code Online (Sandbox Code Playgroud)

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

class Automata machine where
    isDeterministic :: machine -> Bool
    acceptsInput :: machine -> String -> Bool
Run Code Online (Sandbox Code Playgroud)

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

class Automata machine alphabet where
    isDeterministic :: machine -> Bool
    acceptsInput :: machine -> [alphabet] -> Bool
Run Code Online (Sandbox Code Playgroud)

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

{-# LANGUAGE FunctionalDependencies #-}
Run Code Online (Sandbox Code Playgroud)

并强制语言依赖于机器

class Automata machine alphabet | machine -> alphabet where
Run Code Online (Sandbox Code Playgroud)

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

instance Automata (FSM alphabet) alphabet where
Run Code Online (Sandbox Code Playgroud)

工作,这是正确的

instance Automata (FSM alphabet) othertypevariable where
Run Code Online (Sandbox Code Playgroud)

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

 instance Automata (FSM alphabet) Int where
Run Code Online (Sandbox Code Playgroud)

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

class Automata (machine alphabet) where
    isDeterministic :: machine alphabet -> Bool
    acceptsInput :: machine alphabet -> [alphabet] -> Bool
Run Code Online (Sandbox Code Playgroud)

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

data FSM alphabet = FSM [alphabet]
Run Code Online (Sandbox Code Playgroud)

或类似的东西.这还可以定义单个通用实例,例如:

instance Automata (FSM alphabet) where
Run Code Online (Sandbox Code Playgroud)

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

n. *_* m. 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 
    ...
Run Code Online (Sandbox Code Playgroud)

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

class Automata (machine :: * -> *) where
Run Code Online (Sandbox Code Playgroud)

  • 也许你的意思是类可以抽象出任意种类,这是具体类型的正确陪衬.类型构造函数是任意类型级别的箔.例如`Bool`,`Maybe`和`State`是类型构造函数,但是`State s` - 虽然它不是具体类型并且具有更高类型 - 是_not_类型构造函数. (2认同)