【问题标题】:Type Variables in type classes类型类中的类型变量
【发布时间】:2016-06-10 09:33:41
【问题描述】:

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

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

自动机接收输入并确定该输入是否是语言的一部分。上面的课程适用于此。但是等一下,这仅限于字符列表(字符串)如果我想通过 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

这些示例是我正在尝试做的简化版本,但这个问题的解决方案将解决我的问题。我怎么能表达这种东西呢?我可以根据自己的意愿改变类型课程吗?语言扩展是可以接受的。

【问题讨论】:

  • n.m. 的回答是正确的,但你对函数依赖方法不满意的原因对我来说没有意义。

标签: haskell generics types automata


【解决方案1】:

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

【讨论】:

  • 也许你的意思是类可以抽象任意种类,这是对具体类型的正确陪衬。类型构造函数是任意类型级别术语的衬托。例如BoolMaybeState 是类型构造函数,但 State s -- 虽然它不是具体类型并且具有更高的种类 -- 不是类型构造函数。
  • @DanielWagner 您可以将其称为类型构造函数表达式。请参阅the article that started it all (pdf)。但也许你是对的,这是一个过时的术语。
猜你喜欢
  • 2020-04-21
  • 2019-07-20
  • 1970-01-01
  • 2018-05-03
  • 1970-01-01
  • 2016-08-19
  • 2020-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多