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