我正在通过Learn You a Haskell阅读,并且我试图将列表中的元素移动到头部。我想出了我认为是天真的方式,我很好奇,如果有人能告诉我经验丰富的Haskell程序员会做什么。如何在Haskell中移动列表中的元素?
在这个例子中,我有一个整数列表,我想将元素'4',它将索引'3',到列表的头部。
let nums = [1, 2, 3, 4, 5]
(nums !! 3) : delete (nums !! 3) nums
返回[4,1,2,3,5]。
您认为如何?
我正在通过Learn You a Haskell阅读,并且我试图将列表中的元素移动到头部。我想出了我认为是天真的方式,我很好奇,如果有人能告诉我经验丰富的Haskell程序员会做什么。如何在Haskell中移动列表中的元素?
在这个例子中,我有一个整数列表,我想将元素'4',它将索引'3',到列表的头部。
let nums = [1, 2, 3, 4, 5]
(nums !! 3) : delete (nums !! 3) nums
返回[4,1,2,3,5]。
您认为如何?
我会做这种方式:
move n as = head ts : (hs ++ tail ts)
where (hs, ts) = splitAt n as
splitAt
在给定的位置分割的列表,它返回由分裂(这里hs
和ts
)创建的两个部分。应该移动到前面的元素现在在ts
的开头。 head ts
只返回ts
的这第一个元素,tail ts
返回所有内容但是表示第一个元素。函数的结果只是这些部分以正确的顺序组合在一起:hs
与tail ts
级联,并由元素head ts
作为前缀。
toHead n l = let(xs,y:ys)= splitAt n l in y:xs ++ ys – Stephan202 2009-06-24 23:24:43
......请问您能否描述一下请理解代码? – shahkalpesh 2009-06-24 23:31:01
什么是共同发病?
几天前我在读相同的东西。再看一遍&写下如下。
nums !! 3 : [x | x <- nums, (x == (num !! 3)) == False]
两个问题:首先,重复的元素被删除。其次(较少的问题),不等于运算符是(/ =),而不是((a == b)== False)。 – 2009-06-24 23:25:14
好抓。正如你所看到的,我是一个初学者。谢谢纠正:) – shahkalpesh 2009-06-24 23:28:46
有经验的Haskellers很少使用列表索引。我会用突破来避免重复遍历(假设你想匹配的元素“4”,而不是指数“3”):
case break (== 4) [1, 2, 3, 4, 5] of
(a,x:xs) -> x:a ++ xs
(a,xs) -> a ++ xs
如:
Prelude Data.List> case break (== 4) [1, 2, 3, 4, 5] of (a,x:xs) -> x:a ++ xs; (a,xs) -> a ++ xs
[4,1,2,3,5]
我们可以做同样的通过 'splitAt' 索引:
Prelude Data.List> case splitAt 3 [1, 2, 3, 4, 5] of (a,x:xs) -> x:a ++ xs; (a,xs) -> a ++ xs
[4,1,2,3,5]
是的,它与元素4不匹配索引'3'。对不起,混淆 – afrosteve 2009-06-25 04:32:38
还有
toHead n l = l !! n : take n l ++ drop (n+1) l
这可能比使用splitAt
稍微容易一些。
对某事的解决方案小的修改:使用模式的匹配,而不是head
ňtail
“删除”
删除给定元素的第一次出现,所以如果有可能删除错误的元素重复... – sth 2009-06-24 23:25:44