阅读haskell中的数字列表

Joã*_*ias 3 haskell

我正在学习Haskell,我正在解决一个问题,我不得不从列表中删除重复的连续数字,所以我编写了这个程序.

destutter::[Integer] -> [Integer]
destutter [] = []
destutter (fst:snd:t) | fst == snd = destutter (snd : t)
destutter (h:t) = [h] ++ (destutter t)
Run Code Online (Sandbox Code Playgroud)

它适用于我所拥有的输入测试列表

input = [200, 271, 305, 305, 180]
Run Code Online (Sandbox Code Playgroud)

现在我有一个包含大量输入的文本文件,我需要在其上使用我的函数,如果是在C++中我会做类似的事情:

while(cin>> x)
    v.push_back(x);
destutter(x);
Run Code Online (Sandbox Code Playgroud)

但我对Haskell完全不熟悉,我不知道如何用这种语言做到这一点.我在堆栈溢出时找到了这个答案但是无法修改代码供我使用,所以如果有人可以给一个菜鸟,我会非常感激.我的文本文件具有以下结构:

260
221
235
268
...
Run Code Online (Sandbox Code Playgroud)

Cha*_*Rex 5

使用getContents所有从输入stdin.它懒得做,所以不要担心内存不足.

然后将其分成几行lines(或编写自己的函数将其划分为练习行).这使得[String]每个列表元素都是输入中的一行.

然后map read在每个元素上(或编写自己的元素mapread练习函数)将每个元素从a String转换为a Integer.

现在你有了一个[Integer]可以做到的destutter.

destutter::[Integer] -> [Integer]
destutter [] = []
destutter (fst:snd:t) | fst == snd = destutter (snd : t)
destutter (h:t) = [h] ++ (destutter t)

main :: IO ()
main = do
  userInput <- getContents
  let numbers = map read (lines userInput) :: [Integer]
  print $ destutter numbers
Run Code Online (Sandbox Code Playgroud)

关于改善destutter一点点和很多的一些注意事项

如果你正在为学校写作(你destutter肯定是作品),你不应该使用这个,但就目前destutter而言,有一些东西可以帮助你学习.

一个小的风格问题是xxs(yys或或任何那种模式)用于头部和尾部而不是ht.

[x] ++ xs比阅读更难(也更昂贵)x:xs,所以你的第三种模式destutter可以这样做:

destutter (x:xs) = x:destutter xs
Run Code Online (Sandbox Code Playgroud)

(:)用于从模式中的列表前面分离元素以及将元素附加到模式外的列表前面.


现在不用担心这个问题了,但是稍后,在你从头开始编写函数之后,你将开始使用类似的预编写函数Data.List.group,这与将destutter列表中的相等邻居分组到它们中非常相似自己的子列表.如果你取head每个子列表的第一个元素()(它们都是相同的,那么一个与另一个一样好),它会destutter:

import Data.List (group)

destutter :: Eq a => [a] -> [a]
destutter xs = map head (group xs)
Run Code Online (Sandbox Code Playgroud)

所以,基本上,它变成[1, 2, 2, 3][[1], [2, 2], [3]],然后它需要每个子列表的第一个元素[1, 2, 3].

从中可以看出,您已经知道如何编写一个destutter与Haskell中包含的函数非常类似的函数().