Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Haskell中使用递归数据类型创建向后列表_Haskell - Fatal编程技术网

在Haskell中使用递归数据类型创建向后列表

在Haskell中使用递归数据类型创建向后列表,haskell,Haskell,我试图使用Haskell的递归类型创建一个反向列表 data RevList a = Snoc a (RevList a) | Lin deriving Show mkrevlst [] = Lin mkrevlst (x:xs) = mkrevlst xs Snoc x 当我执行mkrevlst[1,2,3]时,我期望的输出是:((Lin Snoc 3)Snoc 2)Snoc 1 当我运行这个程序时,我得到一个错误。我是哈斯克尔的新手&我不知道哪里出了错。 我哪里做错了 谢谢。

我试图使用Haskell的递归类型创建一个反向列表

data RevList a = Snoc a (RevList a) | Lin
    deriving Show 

mkrevlst [] = Lin
mkrevlst (x:xs) = mkrevlst xs Snoc x 
当我执行mkrevlst[1,2,3]时,我期望的输出是:
((Lin Snoc 3)Snoc 2)Snoc 1

当我运行这个程序时,我得到一个错误。我是哈斯克尔的新手&我不知道哪里出了错。 我哪里做错了


谢谢。

我不确定这句话应该是什么,但它没有意义:

mkrevlst (x:xs) = mkrevlst xs Snoc x 
表达式
mkrevlist xs
可能具有类型
RevList a
,因为上面的基本情况返回
Lin
。将此应用于另外两个参数确实会导致类型错误

看起来您希望使用
Snoc
中缀,对吗?在Haskell中,由字母数字字符组成的标识符是前缀,除非被倒勾包围,例如
mkrevlist xs`Snoc`x
。由符号构成的标识符是中缀,除非用括号括起来,中缀数据构造函数必须以冒号开头。因此,您也可以这样定义数据类型:

data RevList a = a :| (RevList a) | Lin
    deriving Show 

另外,请注意,即使您确实使用了
Snoc
中缀,其参数的顺序仍然与您在
mkrevlist

中使用它的顺序相反。一个事物列表要么是空的,要么后面是一个事物列表。这正是您对RevList的定义。它与普通列表同构,根本不反转。实反转列表与普通列表对称定义

事物列表要么为空,要么为空 事物之后是事物的列表

对称地

相反的事物列表要么为空,要么为空 颠倒的事物列表,后跟一个 事情

在Haskell中使用中缀数据构造函数(如camccann的答案中所示)重写此内容,您将得到您所期望的结果。

尝试以下方法:

mkrevlst [] = Lin
mkrevlst (x:xs) = Snoc x (mkrevlst xs)
Snoc构造函数需要两个参数,其中当您只传递一个参数时,即x 它将解决错误,但无法解决创建以下输出的问题:

((Lin Snoc 3) Snoc 2) Snoc 1

为此,您需要修改数据结构

请说明您得到的确切错误。“我得到一个错误”不是一个错误的描述。像这样定义Revlist将更为惯用
data Revlist a=Snoc(Revlist a)a | Lin
。原始定义是一个Cons列表(即没有语法糖的普通列表),它依赖于“智能构造函数”
mrevlist
,使其在概念上成为一个Snoc列表。@n.m,我得到的错误是一个类型错误@stephen tetley,是的,你是对的,它应该是data RevList a=Snoc(RevList a)a | Lin,但我仍在尝试如何编写函数来正确显示列表。当我将其修改为:
data RevList a=Lin | RevList a:| a派生显示
mkrevlst[]=Lin
mkrevlst(x:xs)=mkrevlst xs:|xs
我得到的输出是
((Lin:|[]):|[3]):|[2,3]
这接近我想要的结果。但是你提到的这个符号是什么?如果我用单词
Snoc
替换那个符号,它就不起作用了。@BharatKrishna:它是一个数据构造函数,就像
Snoc
。唯一的区别是,
:|
是运算符样式,因此可以直接以中缀形式编写,并以这种方式显示在默认的
Show
实例中。如果您想使用
Snoc
中缀,请像我的回答中那样用反勾号围绕它,但它不会以这种方式出现在
show
的输出中。谢谢!我对中缀和前缀表示法感到困惑。我试图使用Snoc作为没有背景的中缀,但在编写填充列表的函数时,我真的感到困惑。现在它开始工作了。@BharatKrishna:很公平!在这种情况下,最有用的方法是简单地阅读语言语法的正式规范。但作为一个快速指南:字母数字是前缀,符号是中缀;以大写字母或
开头的标识符是类型/构造函数/类等,以小写字母或任何其他符号开头的标识符是术语/类型变量等。