Haskell初学者问题。。。请给我解释一下

Haskell初学者问题。。。请给我解释一下,haskell,Haskell,我应该写一些haskell程序,但我真的不知道从哪里开始。如果你能给我指一些参考资料来阅读或解释这个问题,我将非常感激。我相信这完全是业余的,但我真的需要一个起点 data DFA q o = DFA (q -> o -> q) q [q] data NFA q o = NFA (q -> o -> [q]) [q] [q] -- I really realy don't understand the dec

我应该写一些haskell程序,但我真的不知道从哪里开始。如果你能给我指一些参考资料来阅读或解释这个问题,我将非常感激。我相信这完全是业余的,但我真的需要一个起点

data DFA q o                =  DFA (q -> o -> q) q [q]
data NFA q o                =  NFA (q -> o -> [q]) [q] [q]
-- I really realy don't understand the declarations here
-- I can guess that q is somewhat related to Q and o to E, but don't get what it really means

data Q                      =  Q0 | Q1 | Q2
                               deriving (Eq, Enum, Bounded)

data E                      =  A | B


-- what does n1 do ??
n1                          :: NFA Q E
n1                          =  NFA d [Q0] [Q2] -- i see [Q0] refers to set of initial states and [Q2] refers to final states :)
                               where
                                   d Q0 A = [Q0]
                                   d Q0 B = [Q0, Q1]
                                   d Q1 _ = [Q2]
                                   d Q2 _ = []


-- the following functions are for me to write
starDFA :: Eq q => DFA q o -> [o] -> Bool
--for the above function, what are the arguments the function takes in ?
--how can we relate q with Q and [o] with [E] ??
任何关于正确起点的解释或参考都会对我很有帮助。 很抱歉问这么愚蠢的问题,但我真的不知道从哪里开始:)

谢谢

可能是目前最好的Haskell教程。我建议你通读整本书,但如果你赶时间的话,我会指出与本作业相关的部分

代码中的主要部分是
数据
声明,因此,一旦您熟悉了基础知识(和),一个很好的切入点就是和

以上内容应足以破译数据声明,并理解
q
vs
q
o
vs
E
之间的关系

现在要实现实际的功能,您需要熟悉如何工作,然后了解足够的Haskell来编写实际的实现。和是本教程中最相关的章节,您可能也会发现这些章节很有用


一旦你说到这一点,如果你被实现困住了,你可以用到目前为止所写的代码发布另一个问题。

从我对Haskell类型声明的一点了解来看,关于DFA和NFA的最初声明是这样说的(比如看NFA):

(左侧:)NFA是一种在其构造中使用两种类型(q和o)的类型。

(右侧:)NFA的实例称为NFA,由三个参数组成:
(1) “(q->o->[q]),表示一个函数,它接受两个参数,一个是q类型,另一个是o类型,并返回q的列表,([q])
(2) “[q]”,表示一个类型为q的值列表
(3) “[q]”,类型为q的值的另一个列表

n1似乎是NFA的一个实例构造,我们看到

n1                          =  NFA d [Q0] [Q2]
因此我们可以推断:
(1) d是一个函数,它接受两个参数“q”和“o”,并返回q的列表
(2) [Q0]是q的列表,并且
(3) [Q2]是q的列表。

事实上,d的定义如下:
d接受两个参数,一个“Q”和一个“E”,并返回一个Q的列表(我们知道它可以是Q0、Q1或Q2)或一个空列表。


我希望这能帮上一点忙,或者也许有人能澄清和纠正我的模糊理解。

在haskell中,我们有三种定义新类型的方法,使用三个不同的关键字,typenewtype,和data

useE :: E -> String
useE A = "This is A"
useE B = "This is B"
在您的示例中,它是正在使用的数据关键字,让我们进一步关注它。
最好从代码中最简单的一个开始

data E = A | B
在这里,我们定义了一个新的类型E,它只能采用两种模式或状态或值。
像这样的类型就是我们所说的总和类型。 我们如何使用it?
主要使用模式匹配

useE :: E -> String
useE A = "This is A"
useE B = "This is B"
现在,代码中有一个更复杂的数据声明

data Q =  Q0 | Q1 | Q2 deriving (Eq, Enum, Bounded)
同样,如前所述,我们有一个和类型,它定义了一个新的类型Q,取三个值,Q0、Q1或Q2。但是我们有一个派生子句,它告诉编译器这种新类型实现了从Eq、Enum、有界类派生(或继承)的方法(或函数)。 这是什么意思?
让我们来看一个函数。 假设你想为Q的每一个值关联一个数字,我们如何才能做到这一点

enumQ :: Q -> Int
enumQ x = fromEnum x
如果您想通过派生子句更深入地了解此特定功能,请阅读已指示的参考资料,然后尝试ghci下的:info Enum。请注意,前面的类型也可以派生自同一类。由于这些类型完全被描述为一组可枚举值的总和(由|区分),因此我们更好地理解为什么称它们为总和类型

useE :: E -> String
useE A = "This is A"
useE B = "This is B"
最后是最困难的数据声明

data DFA q o =  DFA (q -> o -> q) q [q]
data NFA q o =  NFA (q -> o -> [q]) [q] [q]
如果事实上它们几乎是相同的数据定义,那么我将通过第一个数据定义,并让您将第二个数据定义的分析作为练习

data DFA q o = DFA (q -> o -> q) q [q]  
这次我们必须讨论数据构造函数类型构造函数

useE :: E -> String
useE A = "This is A"
useE B = "This is B"
  • 等式的左侧有数据构造函数, 创建数据并为其命名。在这方面,我们有必要的 用于生成此新数据的参数
  • 在等式的右侧,有类型构造函数,用于 建造了这种新型。在这方面,我们有明确的目标 向读者展示这种新类型(数据)是如何建造的管道工程 使用现有类型
请记住,以下是类型:

  • [x]::表示多态列表的类型,例如,[Int]=> 整数列表
  • x::基本类型,现有类型之一(Int、Char、String…)
  • x->y::定义函数的类型,该函数使用类型x生成 y型
  • x->y->z::定义函数类型的类型 键入y以生成类型z。它可以被视为一个函数,接受另一个类型(x->y)的函数并生成一个类型z。这就是我们所说的高阶函数
然后我们的数据声明,放在这个上下文中,是一个数据构造函数,由两个类型参数qo馈送,因此,它返回一个新类型,作为高阶函数、基本类型和列表类型的乘积。这就解释了为什么我们称之为产品类型