Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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
List Haskell-作业-连接两个列表_List_Haskell_Recursion - Fatal编程技术网

List Haskell-作业-连接两个列表

List Haskell-作业-连接两个列表,list,haskell,recursion,List,Haskell,Recursion,我得到一个字符数组,必须将其转换为移动(如下所示) 然而,我只是成功地得到了清单的第一项。我已经尝试了许多方法使createMoves递归,但我不能得到它的权利。你能告诉我吗?如果你的语句的分支是相同的,那么它什么也不做 编程递归函数时,有两种情况。 基本的一个,您应该声明createMoves[]=[]。 递归算法稍微复杂一些;基本上,对于每个x,您都会创建一个move,它是使用递归调用xs构建的列表中附加的第一个元素 更简单的方法是使用map函数。您还可以查看它的实现。 顺便说一下,对于cr

我得到一个字符数组,必须将其转换为移动(如下所示)


然而,我只是成功地得到了清单的第一项。我已经尝试了许多方法使createMoves递归,但我不能得到它的权利。你能告诉我吗?

如果你的
语句的分支是相同的,那么它什么也不做

编程递归函数时,有两种情况。 基本的一个,您应该声明
createMoves[]=[]
。 递归算法稍微复杂一些;基本上,对于每个
x
,您都会创建一个move,它是使用递归调用
xs
构建的列表中附加的第一个元素

更简单的方法是使用
map
函数。您还可以查看它的实现。
顺便说一下,对于
createMove
,如果
s,您可以使用模式匹配而不是许多

您的createMoves函数只对给定列表中的一个元素进行操作

尝试使用
map
功能。换句话说,从以下内容开始您的功能:

createMoves list = Moves (map 

[…]

您可能希望使用防护(即
|
)而不是
如果
那么
否则
您的问题似乎集中在将
xs
递归调用的结果与
createMove x
的结果结合起来。那么,让我们来介绍一个帮助函数,它将处理这个问题

createMoves:: [Char]-> Moves
createMoves (x:xs) =  if xs==[] then Moves [createMove x]
                      else createHelper (createMove x) (createMoves xs)
现在,
createHelper
的类型应该是什么?它的第一个参数是
移动
,第二个参数是
移动
,它应该将第一个参数放在第二个参数中包含的
移动
列表的前面,并将其“重新打包”为
移动
类型的值。要获得
Move
s列表,您需要使用模式匹配,如下所示:

createHelper :: Move -> Moves -> Moves
createHelper m (Moves ms) = Moves (m:ms)
这应该可以解决问题,但是在
上进行所有匹配都会移动
构造函数,然后重新应用它,这有点愚蠢,而且可能效率低下。更好的方法是将
[Char]
逐个转换为
[Move]
,并且仅在最后将
移动到
构造函数。这会导致类似(仍与您的原始想法保持一致)的情况:

createMoveList
是Haskell中经常出现的一种模式,即对列表中的每个元素应用函数(在本例中为
createMove
)。这是
map
函数的精髓(如果您还没有学习过的话,我相信您很快就会在课程中学习到它!)

如果使用该选项,还可以解决当给定空列表时,
createMoves
失败的问题。因此,我的解决方案是:

createMoves :: [Char] -> Moves
createMoves cs = Moves (map createMove cs)


但那是另一个故事

首先,您应该删除
newtype
语句;如果要打印列表,只需使用
Move
类型派生
Show

接下来,您可以使用
map
删除
createMoves
函数中的显式递归。为了将来参考,您可以在上按名称和类型签名查找函数

最后,您可以使用模式匹配来消除针对常量的所有相等性测试。使用
Move
类型的不相关示例如下

isN :: Move -> Bool
isN N = True
isN _ = False

请注意,
字符表示“忽略此值”。如果您还没有介绍模式匹配,那么guards可能仍然比嵌套的
If
s好。

您应该格式化代码……函数不需要Haskell中的括号。您应该只写“createMove x”。顺便说一句,这个
[Char]
不是数组。这是一个列表。为了详细说明,amindfv说:你既不需要它们,也不应该编写它们,因为它们可能会对你的程序的含义带来微妙的变化。例如,
createMove(x:xs)
不同于
createMove x:xs
,因为
的优先级低于
createMove
@fuzzxl,这是因为缺少括号导致问题,而不是出现问题。当你对操作符的优先级还没有把握的时候,放多余的括号是没有错的。这就是我想做的,但是它会干扰类型签名。我试图通过以下方式实现它:createMoves::[Char]->Moves createMoves(x:xs)=如果xs=[],则移动[createMove(x)],否则createMoves(xs):移动[createMove(x)]类型签名有问题的原因是将“Moves”类型构造函数放在递归函数中。如果没有遇到类型问题,列表将如下所示:移动[N,移动E,移动S]。你只需要移动[N,E,S]。将
newtype Moves=Moves[Move]
替换为
newtype Moves=[Move]
,这样可以简化你的代码,而且你不需要每次列出移动列表时都使用构造函数。@Chris-你是说
type Moves=[Move]
?@John:yep,忘了删除这个新的好答案+1.不试图修复任何未损坏的部件。:-)
createMoves :: [Char] -> Moves
createMoves cs = Moves (map createMove cs)
createMoves = Moves . map createMove
isN :: Move -> Bool
isN N = True
isN _ = False