I'm learning Haskell and I was working in a problem where I had to remove repeated consecutive numbers from a list, so I wrote this program.
destutter::[Integer] -> [Integer]
destutter [] = []
destutter (fst:snd:t) | fst == snd = destutter (snd : t)
destutter (h:t) = [h] ++ (destutter t)
It works fine for the input test that I had which was a list
input = [200, 271, 305, 305, 180]
now I have a text file with a lot of inputs and I need to use my function on it, if it was in C++ I would do something like:
while(cin>> x)
v.push_back(x);
destutter(x);
But I'm completely new to Haskell and I have no idea how I would do that on this language. I found this answer on stack overflow but was not able to modify the code for my use, so if someone could give a noob a hand I would be very thankful. My text file has the following structure:
260
221
235
268
...
Elem Function This function is used to check whether the supplied list contains a specific element or not. Accordingly, it either returns a true or a false. The following code checks whether the supplied list of elements contains the value 786.
Use getContents
to get all input from stdin
. It does so lazily, so don't worry about running out of memory.
Then separate it into lines with lines
(or write your own function to divide it into lines for practice). This makes a [String]
with each list element being a line in the input.
Then map
read
over each element (or write your own map
and read
functions for practice) to turn each element from a String
into an Integer
.
Now you have an [Integer]
that you can 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
a little and a lotYou shouldn't use this if you're writing an assignment for school (your destutter
definitely works), but as far as destutter
goes, there are a few things to help your learning.
A minor stylistic issue is that x
and xs
(or y
and ys
or anything of that pattern) are used for head and tail rather than h
and t
.
[x] ++ xs
is harder to read (and more expensive) than x:xs
, so your third pattern for destutter
can be done like this:
destutter (x:xs) = x:destutter xs
(:)
is useful for detaching elements from the front of a list in patterns and for attaching elements to the front of a list outside of patterns.
Don't worry about this so much now, but later on, after you get the hang of writing functions from scratch, you'll begin to use prewritten functions like Data.List.group
, which is quite similar to destutter
as it groups equal neighbors in a list into their own sublist. If you take the first element (head
) of each sublist (they're all equal, so one's as good as another), it does destutter
:
import Data.List (group)
destutter :: Eq a => [a] -> [a]
destutter xs = map head (group xs)
So, basically, it turns [1, 2, 2, 3]
into [[1], [2, 2], [3]]
, then it takes the first element of each sublist to get [1, 2, 3]
.
One thing to take from that is that you already know how to write a function (destutter
) quite similar to those that they include with Haskell.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With