类型变量 类
Type Variables in type classes
我有一个关于 classes 类型的奇怪问题。所以你可以这样定义一个基本类型class:
class Property x where
checkThing :: x -> Int -> Bool
transformThing :: x -> x
如果你想要一个带有多个参数的类型class,你可以启用:
{-# LANGUAGE MultiParamTypeClasses #-}
这将使您可以执行以下操作:
class Property x y where
checkThing :: x -> Int -> Bool
transformThing :: x -> y -> Int
这是我的问题:假设我想为自动机(接受语言的类型)编写一个类型 class。我会写一个看起来像这样的类型 class:
class Automata machine where
isDeterministic :: machine -> Bool
acceptsInput :: machine -> String -> Bool
自动机接受输入并决定该输入是否属于某种语言。上面的 class 适用于此。但是等等,这仅限于字符列表(字符串),如果我想通过自动机进行概括怎么办?好吧,我可以在我的 class 定义中添加另一个变量:
class Automata machine alphabet where
isDeterministic :: machine -> Bool
acceptsInput :: machine -> [alphabet] -> Bool
嗯,没关系。但是字母可能与机器没有直接关系。不过我很幸运!我可以启用:
{-# LANGUAGE FunctionalDependencies #-}
并强制语言依赖于机器
class Automata machine alphabet | machine -> alphabet where
好的,现在当我创建自动机实例时,我可以要求字母表与机器相关联。例如:
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
这些示例是我正在尝试做的简化版本,但是这个问题的解决方案将解决我的问题。我怎么能去表达这样的东西呢?我可以屈服于我的意志吗?语言扩展是可以接受的。
Haskell 类型 类 可以抽象任意种类。这意味着 类 类型的参数本身可以有参数。熟悉的示例包括 Functor
和 Monad
,它们接受 []
或 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
我有一个关于 classes 类型的奇怪问题。所以你可以这样定义一个基本类型class:
class Property x where
checkThing :: x -> Int -> Bool
transformThing :: x -> x
如果你想要一个带有多个参数的类型class,你可以启用:
{-# LANGUAGE MultiParamTypeClasses #-}
这将使您可以执行以下操作:
class Property x y where
checkThing :: x -> Int -> Bool
transformThing :: x -> y -> Int
这是我的问题:假设我想为自动机(接受语言的类型)编写一个类型 class。我会写一个看起来像这样的类型 class:
class Automata machine where
isDeterministic :: machine -> Bool
acceptsInput :: machine -> String -> Bool
自动机接受输入并决定该输入是否属于某种语言。上面的 class 适用于此。但是等等,这仅限于字符列表(字符串),如果我想通过自动机进行概括怎么办?好吧,我可以在我的 class 定义中添加另一个变量:
class Automata machine alphabet where
isDeterministic :: machine -> Bool
acceptsInput :: machine -> [alphabet] -> Bool
嗯,没关系。但是字母可能与机器没有直接关系。不过我很幸运!我可以启用:
{-# LANGUAGE FunctionalDependencies #-}
并强制语言依赖于机器
class Automata machine alphabet | machine -> alphabet where
好的,现在当我创建自动机实例时,我可以要求字母表与机器相关联。例如:
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
这些示例是我正在尝试做的简化版本,但是这个问题的解决方案将解决我的问题。我怎么能去表达这样的东西呢?我可以屈服于我的意志吗?语言扩展是可以接受的。
Haskell 类型 类 可以抽象任意种类。这意味着 类 类型的参数本身可以有参数。熟悉的示例包括 Functor
和 Monad
,它们接受 []
或 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