Haskell首发问题......请向我解释一下

use*_*333 5 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 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] ??
Run Code Online (Sandbox Code Playgroud)

对正确起点的任何解释或引用对我都非常有帮助.很抱歉问这么愚蠢的问题,但我真的不知道从哪里开始:)

谢谢

sha*_*ang 17

学习Haskell的好消息吧!可能是目前最好的Haskell教程.我建议阅读整篇文章,但如果你赶时间,我会指出一些更相关的部分.

您给出的代码中的主要部分是data声明,因此一旦您熟悉了基础知识(第2 章和第3章第1部分),潜入的好地方是代数数据类型简介,类型变量输入参数.

以上内容足以破译数据声明并理解qvs Qovs 之间的关系E.

现在要实现实际的功能,你需要熟悉确定性有限自动机如何工作,然后知道足够的Haskell来编写实际的实现.第4第5章是本教程最相关的章节,你可能也发现了标准库列表功能部分有用.

一旦你达到这一点,如果你坚持实现,你可以发布另一个问题与你迄今为止编写的代码.


zur*_*rgl 6

在Haskell我们有三种方式来定义新的类型,使用三个不同的关键字,类型,NEWTYPE数据.

在您的示例中,它是正在使用的数据关键字,让我们更多地关注它.
最好从代码中最简单的一个开始

data E = A | B
Run Code Online (Sandbox Code Playgroud)

在这里,我们定义了一个新类型E,它只能采用两种模式状态.
像这样的类型就是我们所说的和类型.我们怎么用呢?
主要是模式匹配.

useE :: E -> String
useE A = "This is A"
useE B = "This is B"
Run Code Online (Sandbox Code Playgroud)

现在,来自代码的更复杂的数据声明.

data Q =  Q0 | Q1 | Q2 deriving (Eq, Enum, Bounded)
Run Code Online (Sandbox Code Playgroud)

同样,如前所述,我们有一个定义新类型Q 的和类型,取三个值,Q0,Q1或Q2.但是我们有一个派生子句,它告诉编译器这个新类型实现了从Eq,Enum,Bounded类派生(或继承)的方法(或函数).那是什么意思 ?
我们来看看一个函数.
想象一下,您想要为Q的每个值关联一个数字,我们如何才能执行该操作?

enumQ :: Q -> Int
enumQ x = fromEnum x
Run Code Online (Sandbox Code Playgroud)

如果您想通过derinding子句提供有关此特定功能的更多信息,请阅读已指示的资源并尝试:在ghci下的info Enum.请注意,以前的类型也可以派生自同一个类.由于这些类型被完全描述为可枚举值集合的总和(由|区分),我们更好地理解为什么我们称它们为sum类型.

最后是最困难的数据声明.

data DFA q o =  DFA (q -> o -> q) q [q]
data NFA q o =  NFA (q -> o -> [q]) [q] [q]
Run Code Online (Sandbox Code Playgroud)

如果事实上它们几乎是相同的数据定义,那么我将通过第一个数据定义,并让你分析第二个作为练习.

data DFA q o = DFA (q -> o -> q) q [q]  
Run Code Online (Sandbox Code Playgroud)

这次我们必须讨论数据构造函数类型构造函数.

  • 在等式的左侧,有数据构造函数,用于构建数据并为其命名.在这一方面,我们有用于构建这些新数据的必需参数.
  • 在相等的右边,有类型构造函数,来构建这个新类型.在这一方面,我们有明确的管道工程,向读者展示如何使用现有类型构建这种新类型(数据).

现在请记住,以下是类型,

  • [x] :::表示多态列表的类型,示例,[Int] => Int的列表
  • x :::基本类型,现有的类型之一(Int,Char,String ...)
  • x - > y :::定义函数的类型采用类型x生成类型y.
  • x - > y - > z :::定义函数的类型,类型x和类型y生成类型z.这可以作为函数查看类型(x-> y)的另一个函数并生成类型z.这就是我们所说的高阶函数.

然后我们的数据声明,在这个上下文中,是一个数据构造函数,由两个类型参数qo提供,因此,它返回一个新类型作为高阶函数的基本类型和列表类型的乘积.这解释了为什么我们称之为产品类型.

它应该足够了,现在,自己推断,回答你的问题n1是什么?

祝好运.