阅读haskell中的数字列表

时间:2018-09-27 02:30:03

标签: haskell

我正在学习Haskell,当时我正在解决一个必须从列表中删除重复的连续数字的问题,所以我写了这个程序。

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

对于我进行过的输入测试(列表)来说效果很好

input = [200, 271, 305, 305, 180]

现在我有一个带有很多输入的文本文件,我需要在上面使用我的函数,如果它是C ++,我会做类似的事情:

while(cin>> x)
    v.push_back(x);
destutter(x);

但是我对Haskell完全陌生,我也不知道如何用这种语言来做到这一点。我在堆栈溢出时找到了this的答案,但无法修改代码供我使用,因此如果有人可以帮助菜鸟,我将非常感激。我的文本文件具有以下结构:

260
221
235
268
...

1 个答案:

答案 0 :(得分:5)

使用getContentsstdin获取所有输入。它是如此懒惰,所以不必担心内存不足。

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

然后在每个元素上map read(或编写自己的mapread函数进行练习)将每个元素从String变成一个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

关于destutter的一些改进之处

如果您正在编写学校作业(您的destutter肯定有效),则不应使用此功能,但是就destutter而言,有一些方法可以帮助您的学习。

一个较小的样式问题是xxs(或yys或任何类似模式)用于头尾,而不是{{1 }}和h

t[x] ++ xs更难读(且更昂贵),因此可以像这样完成x:xs的第三个模式:

destutter

destutter (x:xs) = x:destutter xs 对于在样式中从列表的开头分离元素非常有用,并且在将样式之外的元素附加到列表的开头


现在不必担心太多,但是稍后,从头开始编写函数之后,您将开始使用(:)之类的预编写函数,该函数与{{ 1}},因为它将列表中的相等邻居分为自己的子列表。如果采用每个子列表的第一个元素(Data.List.group)(它们都是相等的,那么一个和另一个一样好),则它会destutter

head

因此,基本上,它将destutter转换为import Data.List (group) destutter :: Eq a => [a] -> [a] destutter xs = map head (group xs) ,然后它使用每个子列表的第一个元素来获得[1, 2, 2, 3]

从中得到的一件事是,您已经知道如何编写与Haskell所包含的函数非常相似的函数([[1], [2, 2], [3]])。