n:th element of a list of integers. [Homework] - haskell

Hi im required to find what is the n:th element of from a [Int]
I came up with code
getelemt::[Int]->Int->Int
getelemt _ 0 = 0
getelemt (x:xs) n | x==n = x
| otherwise = getelemt xs n
i know getelemt (x:xs) n | x==n = x it returns where my x element == input element
As the logic i think i need to keep up how may times does this function got recursioned how to keep this index ? or any other method available ?
new Code
getelemt::[Int]->Int->Int
getelemt _ n = 0
getelemt (x:xs) n | n==0 = x
| otherwise = getelemt xs n-1

Can't you just use !!?
Anyway your function (getelemt (x:xs) i) should work like this:
if i is 0, your functions returns x (the first element of the list it gets as parameter: x:xs)
otherwise it recurses, returning getelem xs (i-1)
Edit after OP's update:
You don't need getelemt _ n = 0: it says getelemt should always be 0, since it always matches.
getelemt xs n-1 is equivalent to (getelemt xs n)-1 which is not what you want, you need to put n-1 into parenthesis, since infix functions have a lower precedence.
I'd suggest you to study Haskell from here, it's great guide for beginners. Read the first few chapters, they'll run by very quickly and nicely, and you'll understand Haskell a lot more deeply.

Related

Haskell find divisors based on comprehension method

I need a little help understanding a comprehension method function.
compdivides :: Integer -> [Integer]
compdivides x
| x > 0 = [a | a <-[1..div x 2], mod x a == 0] ++ [x]
| otherwise = compdivides (abs x)
I understand that if x is positive we do the 3rd line otherwise the 4th line.
In the third line we check whether mod x a == 0 only then do we do everything else.
However, I cannot seem to understand this part a <-[1..div x 2] What exactly happens here?
Also, why do we do this at the end ++ [x] ? What exactly are we doing here anyways?
itemTotal :: [(String, Float)] -> [(String, Float)]
itemTotal [] = []
itemTotal [x] = [x]
I am having some trouble with this as well.
I understand that if the list is empty we simply return an empty list.
However, what are we saying here? itemTotal [x] = [x] That if the list only has one thing we simply return that one thing?
Thank you so much for the help!
However, I cannot seem to understand this part a <-[1..div x 2] What exactly happens here?
This is a generator of the list comprehension. The list comprehension:
[ a | a <- [1 .. div x 2 ], mod x a == 0 ]
will evaluate such that a takes each item in the list (so 1, 2, …, x/2), and in case mod x a == 0 (x is dividable by a), it will add a to the list.
Also, why do we do this at the end ++ [x] ? What exactly are we doing here anyways?
It appends x at the end of the list. This is done because a number x is always dividable by itself (x), since the a <- [1 .. div x 2] stops at div x 2, it will never check if x divides x.
The function will get stuck in an infinite loop for compdivides 0, so you might want to rewrite the function to cover this case as well.
However, what are we saying here? itemTotal [x] = [x] That if the list only has one thing we simply return that one thing?
Yes. Usually a pattern like itemTotal (x : xs) = x : itemTotal xs is used where we thus return a list where x is the first item, and we recurse on the tail of the list xs.
Your itemTotal function however only makes a copy of the list for the first two clauses. You thus can simply define itemTotal = id. Likely you will need to rewrite the function to determine the total of the items in the list.

Breaking down a haskell function

I'm reading Real world haskell book again and it's making more sense. I've come accross this function and wanted to know if my interpretation of what it's doing is correct. The function is
oddList :: [Int] -> [Int]
oddList (x:xs) | odd x = x : oddList xs
| otherwise = oddList xs
oddList _ = []
I've read that as
Define the function oddList which accepts a list of ints and returns a list of ints.
Pattern matching: when the parameter is a list.
Take the first item, binding it to x, leaving the remainder elements in xs.
If x is an odd number prepend x to the result of applying oddList to the remaining elements xs and return that result. Repeat...
When x isn't odd, just return the result of applying oddList to xs
In all other cases return an empty list.
1) Is that a suitable/correct way of reading that?
2) Even though I think I understand it, I'm not convinced I've got the (x:xs) bit down. How should that be read, what's it actually doing?
3) Is the |...| otherwise syntax similar/same as the case expr of syntax
1 I'd make only 2 changes to your description:
when the parameter is a nonempty list.
f x is an odd number prepend x to the result of applying oddList to the remaining elements xs and return that result. [delete "Repeat...""]
Note that for the "_", "In all other cases" actually means "When the argument is an empty list", since that is the only other case.
2 The (x:xs) is a pattern that introduces two variables. The pattern matches non empty lists and binds the x variable to the first item (head) of the list and binds xs to the remainder (tail) of the list.
3 Yes. An equivalent way to write the same function is
oddList :: [Int] -> [Int]
oddList ys = case ys of { (x:xs) | odd x -> x : oddList xs ;
(x:xs) | otherwise -> oddList xs ;
_ -> [] }
Note that otherwise is just the same as True, so | otherwise could be omitted here.
You got it right.
The (x:xs) parts says: If the list contains at least one element, bind the first element to x, and the rest of the list to xs
The code could also be written as
oddList :: [Int] -> [Int]
oddList (x:xs) = case (odd x) of
True -> x : oddList xs
False -> oddList xs
oddList _ = []
In this specific case, the guard (|) is just a prettier way to write that down. Note that otherwise is just a synonym for True , which usually makes the code easier to read.
What #DanielWagner is pointing out, is we in some cases, the use of guards allow for some more complex behavior.
Consider this function (which is only relevant for illustrating the principle)
funnyList :: [Int] -> [Int]
funnyList (x1:x2:xs)
| even x1 && even x2 = x1 : funnyList xs
| odd x1 && odd x2 = x2 : funnyList xs
funnyList (x:xs)
| odd x = x : funnyList xs
funnyList _ = []
This function will go though these clauses until one of them is true:
If there are at least two elements (x1 and x2) and they are both even, then the result is:
adding the first element (x1) to the result of processing the rest of the list (not including x1 or x2)
If there are at least one element in the list (x), and it is odd, then the result is:
adding the first element (x) to the result of processing the rest of the list (not including x)
No matter what the list looks like, the result is:
an empty list []
thus funnyList [1,3,4,5] == [1,3] and funnyList [1,2,4,5,6] == [1,2,5]
You should also checkout the free online book Learn You a Haskell for Great Good
You've correctly understood what it does on the low level.
However, with some experience you should be able to interpret it in the "big picture" right away: when you have two cases (x:xs) and _, and xs only turns up again as an argument to the function again, it means this is a list consumer. In fact, such a function is always equivalent to a foldr. Your function has the form
oddList' (x:xs) = g x $ oddList' xs
oddList' [] = q
with
g :: Int -> [Int] -> [Int]
g x qs | odd x = x : qs
| otherwise = qs
q = [] :: [Int]
The definition can thus be compacted to oddList' = foldr g q.
While you may right now not be more comfortable with a fold than with explicit recursion, it's actually much simpler to read once you've seen it a few times.
Actually of course, the example can be done even simpler: oddList'' = filter odd.
Read (x:xs) as: a list that was constructed with an expression of the form (x:xs)
And then, make sure you understand that every non-empty list must have been constructed with the (:) constructor.
This is apparent when you consider that the list type has just 2 constructors: [] construct the empty list, while (a:xs) constructs the list whose head is a and whose tail is xs.
You need also to mentally de-sugar expressions like
[a,b,c] = a : b : c : []
and
"foo" = 'f' : 'o' : 'o' : []
This syntactic sugar is the only difference between lists and other types like Maybe, Either or your own types. For example, when you write
foo (Just x) = ....
foo Nothing = .....
we are also considering the two base cases for Maybe:
it has been constructed with Just
it has been constructed with Nothing

Haskell - get nth element without "!!"

I need to get the nth element of a list but without using the !! operator. I am extremely new to haskell so I'd appreciate if you can answer in more detail and not just one line of code. This is what I'm trying at the moment:
nthel:: Int -> [Int] -> Int
nthel n xs = 0
let xsxs = take n xs
nthel n xs = last xsxs
But I get: parse error (possibly incorrect indentation)
There's a lot that's a bit off here,
nthel :: Int -> [Int] -> Int
is technically correct, really we want
nthel :: Int -> [a] -> a
So we can use this on lists of anything (Optional)
nthel n xs = 0
What you just said is "No matter what you give to nthel return 0". which is clearly wrong.
let xsxs = ...
This is just not legal haskell. let ... in ... is an expression, it can't be used toplevel.
From there I'm not really sure what that's supposed to do.
Maybe this will help put you on the right track
nthelem n [] = <???> -- error case, empty list
nthelem 0 xs = head xs
nthelem n xs = <???> -- recursive case
Try filling in the <???> with your best guess and I'm happy to help from there.
Alternatively you can use Haskell's "pattern matching" syntax. I explain how you can do this with lists here.
That changes our above to
nthelem n [] = <???> -- error case, empty list
nthelem 0 (x:xs) = x --bind x to the first element, xs to the rest of the list
nthelem n (x:xs) = <???> -- recursive case
Doing this is handy since it negates the need to use explicit head and tails.
I think you meant this:
nthel n xs = last xsxs
where xsxs = take n xs
... which you can simplify as:
nthel n xs = last (take n xs)
I think you should avoid using last whenever possible - lists are made to be used from the "front end", not from the back. What you want is to get rid of the first n elements, and then get the head of the remaining list (of course you get an error if the rest is empty). You can express this quite directly as:
nthel n xs = head (drop n xs)
Or shorter:
nthel n = head . drop n
Or slightly crazy:
nthel = (head .) . drop
As you know list aren't naturally indexed, but it can be overcome using a common tips.
Try into ghci, zip [0..] "hello", What's about zip [0,1,2] "hello" or zip [0..10] "hello" ?
Starting from this observation, we can now easily obtain a way to index our list.
Moreover is a good illustration of the use of laziness, a good hint for your learning process.
Then based on this and using pattern matching we can provide an efficient algorithm.
Management of bounding cases (empty list, negative index).
Replace the list by an indexed version using zipper.
Call an helper function design to process recursively our indexed list.
Now for the helper function, the list can't be empty then we can pattern match naively, and,
if our index is equal to n we have a winner
else, if our next element is empty it's over
else, call the helper function with the next element.
Additional note, as our function can fail (empty list ...) it could be a good thing to wrap our result using Maybe type.
Putting this all together we end with.
nth :: Int -> [a] -> Maybe a
nth n xs
| null xs || n < 0 = Nothing
| otherwise = helper n zs
where
zs = zip [0..] xs
helper n ((i,c):zs)
| i == n = Just c
| null zs = Nothing
| otherwise = helper n zs

Foldr Application

Recently I am trying to solve a problem using Foldr. The task is following:
In:[5,1,3,8,2,4,7,1]
Out:[16,8]
It means, I will double those element of the input list which is in the odd index position and even digit. I wrote the program without using foldr which is following:(It shows pattern match failure: head[])
findPos list elt =
map fst $ filter ((elt==).snd) $ zip [0..] list
doublePos [] = []
doublePos (x:xs)
| ((head(findPos xs x)`mod` 2) /= 0) && (x `mod` 2 == 0) =
[2*x] ++ doublePos xs
| otherwise = doublePos xs
How do I write this program using foldr?
foldr isn't really a good choice for this function, as you need to pass the parity of the index of each element from the front of the list.
A list comprehension is probably the cleanest:
doublePos xs = [2*x | (i,x) <- zip [0..] xs, even x, odd i]
or you could use plain old recursion:
doublePos' (_:x:xs)
| even x = (2*x) : doublePos' xs
| otherwise = doublePos' xs
doublePos' _ = []
Though, if you must use foldr, you can do it by having the accumulator be a function
which takes the parity of the current index as an argument:
doublePos'' xs = foldr step (const []) xs False where
step x next p
| p && even x = 2*x : next (not p)
| otherwise = next (not p)
Why your existing code gives you a pattern match failure: doublePos [5,1,3,8,2,4,7,1] matches the second equation with x = 5 and xs = [1,3,8,2,4,7,1]. This causes head (findPos [1,3,8,2,4,7,1] 5) to be evaluated, but that reduces to head [] and you get your error.
To expand on this: what you seem to be hoping to get out of findPos is the index of the current element, relative to the start of the original list. But what you actually get out of it is the index of the next occurrence of the current element, relative to the next element... and if it doesn't occur again, you get an error.
(Using characters as list elements here to avoid confusion between list indices and list elements.)
0 1 2 3 4 5 6 7 8 9 10 <-- indices relative to start
'H':'e':'l':'l':'o':' ':'t':'h':'e':'r':'e':[] <-- original list
| |
x = 'e' | V say we're here
xs = 'l':'l':'o':' ':'t':'h':'e':'r':'e':[] head (findPos xs x) = 6 but we wanted 1
| ^
x = 'o' say we're here instead
xs = ' ':'t':'h':'e':'r':'e':[] head (findPos xs x) = error "head []" but we wanted 4
The only way this can possibly work is if you pass the original list to findPos. But the only list you have available is that part of the original list you have not yet recursed into. Anyway, there are better ways of doing this, as seen in hammar's answer.

How to remove an element from a list in Haskell?

The function I'm trying to write should remove the element at the given index from the given list of any type.
Here is what I have already done:
delAtIdx :: [x] -> Int -> [x]
delAtIdx x y = let g = take y x
in let h = reverse x
in let b = take (((length x) - y) - 1) h
in let j = g ++ (reverse b)
in j
Is this correct? Could anyone suggest another approach?
It's much simpler to define it in terms of splitAt, which splits a list before a given index. Then, you just need to remove the first element from the second part and glue them back together.
reverse and concatenation are things to avoid if you can in haskell. It looks like it would work to me, but I am not entirely sure about that.
However, to answer the "real" question: Yes there is another (easier) way. Basically, you should look in the same direction as you always do when working in haskell: recursion. See if you can make a recursive version of this function.
Super easy(I think):
removeIndex [] 0 = error "Cannot remove from empty array"
removeIndex xs n = fst notGlued ++ snd notGlued
where notGlued = (take (n-1) xs, drop n xs)
I'm a total Haskell noob, so if this is wrong, please explain why.
I figured this out by reading the definition of splitAt. According to Hoogle, "It is equivalent to (take n xs, drop n xs)". This made me think that if we just didn't take one extra number, then it would be basically removed if we rejoined it.
Here is the article I referenced Hoogle link
Here's a test of it running:
*Main> removeIndex [0..10] 4
[0,1,2,4,5,6,7,8,9,10]
deleteAt :: Int -> [a] -> [a]
deleteAt 0 (x:xs) = xs
deleteAt n (x:xs) | n >= 0 = x : (deleteAt (n-1) xs)
deleteAt _ _ = error "index out of range"
Here is my solution:
removeAt xs n | null xs = []
removeAt (x:xs) n | n == 0 = removeAt xs (n-1)
| otherwise = x : removeAt xs (n-1)
remove_temp num l i | elem num (take i l) == True = i
| otherwise = remove_temp num l (i+1)
remove num l = (take (index-1) l) ++ (drop index l)
where index = remove_temp num l 1
Call 'remove' function with a number and a list as parameters. And you'll get a list without that number as output.
In the above code, remove_temp function returns the index at which the number is present in the list. Then remove function takes out the list before the number and after the number using inbuilt 'take' and 'drop' function of the prelude. And finally, concatenation of these two lists is done which gives a list without the input number.

Resources