Haskell 类型类中的类型变量
我有一个关于类型类的奇怪问题。因此,您可以定义如下所示的基本类型类:Haskell 类型类中的类型变量,haskell,generics,types,automata,Haskell,Generics,Types,Automata,我有一个关于类型类的奇怪问题。因此,您可以定义如下所示的基本类型类: class Property x where checkThing :: x -> Int -> Bool transformThing :: x -> x class Automata machine where isDeterministic :: machine -> Bool acceptsInput :: machine -> String ->
class Property x where
checkThing :: x -> Int -> Bool
transformThing :: x -> x
class Automata machine where
isDeterministic :: machine -> Bool
acceptsInput :: machine -> String -> Bool
如果希望具有具有多个参数的类型类,可以启用:
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
这将允许您执行以下操作:
class Property x y where
checkThing :: x -> Int -> Bool
transformThing :: x -> y -> Int
这是我的问题:假设我想为自动机(接受一种语言的类型)编写一个类型类。我将编写一个类型类,其外观如下:
class Property x where
checkThing :: x -> Int -> Bool
transformThing :: x -> x
class Automata machine where
isDeterministic :: machine -> Bool
acceptsInput :: machine -> String -> Bool
自动机接收输入并决定该输入是否是语言的一部分。上面的课程将适用于此。但是等等,这仅限于字符(字符串)列表,如果我想用自动机来概括呢?我可以在我的类定义中添加另一个变量:
class Automata machine alphabet where
isDeterministic :: machine -> Bool
acceptsInput :: machine -> [alphabet] -> Bool
嗯,没关系。但字母表可能和机器并没有直接关系。不过我很幸运!我可以启用:
{-# LANGUAGE MultiParamTypeClasses #-}
{-# 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
如果我可以在正在为其定义的数据实例上指定特定的类型参数。例如,可以为automata定义的数据如下所示:
data FSM alphabet = FSM [alphabet]
或者类似的。这还允许定义单个通用实例,例如:
instance Automata (FSM alphabet) where
这些例子是我试图做的一个简化版本,但这个问题的解决方案可以解决我的问题。我怎么能这样表达呢?我能随心所欲地学习打字吗?语言扩展是可以接受的。Haskell类型的类可以对任意类型进行抽象。这意味着o类型类的参数本身可以有参数。常见的例子包括
函子
和单子
,它们接受像[]
或可能
这样的参数。下面是一种使用*→*代码>种类:
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}
可以明确显示机器的类型:
class Automata (machine :: * -> *) where
Haskell类型的类可以抽象任意类型。这意味着o类型类的参数本身可以有参数。常见的例子包括函子
和单子
,它们接受像[]
或可能
这样的参数。下面是一种使用*→*代码>种类:
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}
可以明确显示机器的类型:
class Automata (machine :: * -> *) where
也许你的意思是类可以抽象任意类型,这是对具体类型的正确衬托。类型构造函数是任意类型级别术语的陪衬。e、 g.Bool
、可能
、和状态
都是类型构造函数,但是状态s
——虽然它不是一个具体的类型,并且具有更高的种类——却不是一个类型构造函数。@DanielWagner您可以称它为类型构造函数表达式。见(pdf)。但也许你是对的,这是一个过时的术语。也许你的意思是类可以抽象任意类型,这是对具体类型的正确衬托。类型构造函数是任意类型级别术语的陪衬。e、 g.Bool
、可能
、和状态
都是类型构造函数,但是状态s
——虽然它不是一个具体的类型,并且具有更高的种类——却不是一个类型构造函数。@DanielWagner您可以称它为类型构造函数表达式。见(pdf)。但也许你是对的,这是一个过时的术语。n.m.的答案是正确的,但你不满意函数依赖方法的原因对我来说没有意义。n.m.的答案是正确的,但你不满意函数依赖方法的原因对我来说没有意义。