Understanding Haskell - list

Can someone help me understand how this function in Haskell works?
f :: Eq t => t -> [t] -> [t]
f x [] = []
f x (y: ys) | (x==y) = [x]
f x (y: ys) | otherwise = y : f x ys
My understanding so far is that the function f tests the equality of variable t and list of type t and returns a list of type t.
If passed x and an empty set f will return an empty set.
If passed x and a list where y heads the list or x is equal to y then it will return a list containing x.
If passed x and a list where y heads the list or anything else then it will return a list headed by y and the contents of the list returned from a recursive call to f using x and list ys?
Is that correct?
Secondly I don't know what the equality being tested is? Is it testing to see if x is contained within a listor checking to see if x is heading the list?
Can someone explain please?

Probably better to pay attention to the terminal cases. Empty list being one and head of list equals to the given element the other. Otherwise, it's going to recursively operate until one of the two cases happens.
By hand go over what will be the returned list for these two
f 3 [1,2]
and
f 3 [1,2,3,4,5]
It's better to discover yourself but I guess you're not there yet.
For
f 3 [1,2] = 1: (f 3 [2]) = 1: 2: (f 3 []) = [1,2]
other one similarly
f 3 [1..5] = 1: (f 3 [2..5]) = 1: 2: (f 3 [3,4,5]) = 1: 2: [3] = [1,2,3]

Related

Circular maps in haskell

I'm tasked with implementing a function that returns the Thue-Morse sequence all the way through. I've done it through primitive recursion but now I have to do it with a circular list (using list comprehension), and it'd have to return this when I call take on it:
>take 4 thueSeq
[[0],[0,1],[0,1,1,0],[0,1,1,0,1,0,0,1]]
Here's my (horrible) attempt at implementation:
> thueSeq = 0: [x | x <- zipWith (mod) (tail thueSeq) [1] ]
I'm aware right off the bat that it's wrong (the head is supposed to be [0], not 0) but writing [0] ++ [0,1] ++ ... didn't return a list of lists anyway.
My question is, first off, how do I "start off" the list with [[0],[0,1]] because from what I've seen with circular lists, they have the base cases and then recurse through. Secondly, my list comprehension is trying to apply (mod x 1) to each value, but that'd also be wrong since [[0,1]] would turn into [[0,1,0]] instead of [[0,1,1,0]]. So I'm thinking I have to apply it on every other element in the list (the 1st element, 3rd, 5th, etc.)?
From what I understand...
I have just written a simple flip function that maps 1 to 0 and 0 to 1
flipBit 1 = 0
flipBit 0 = 1
the function h takes a list and joins that list with the flipped version of the list
h xs = xs ++ (map flipBit xs)
*Main> h [0]
[0,1]
The main function fseq takes a list as an argument. It conses the argument into the recursive call
fseq xs = xs : fseq (h xs)
*Main> take 4 $ fseq [0]
[[0],[0,1],[0,1,1,0],[0,1,1,0,1,0,0,1]]
Haskell provides the function iterate :: (a -> a) -> a -> [a] that does exactly this.
We can now wrap this as follows:
thue_morse = fseq [0]
or using the function iterate
thue_morse = iterate h [0]
both give the result
*Main> take 4 thue_morse
[[0],[0,1],[0,1,1,0],[0,1,1,0,1,0,0,1]]
If you wanted to use list comprehensions, you could write something like this:
h xs = xs ++ (map flipBit xs)
thue_morse = [0] : [ h x | x <- thue_morse]

Haskell Function that Takes A Pair of Values and a List

My homework has been driving me up the wall. I am supposed to write a function called myRepl that takes a pair of values and a list and returns a new list such that each occurrence of the first value of the pair in the list is replaced with the second value.
Example:
ghci> myRepl (2,8) [1,2,3,4]
> [1,8,3,4].
So far I have something like this (but its very rough and not working well at all. I need help with the algorithm:
myRep1 (x,y) (z:zs) =
if null zs then []
else (if x == z then y : myRep1 zs
else myRep1 zs )
I don't know how to create a function that takes a pair of values and a list. I'm not sure what the proper syntax is for that, and I'm not sure how to go about the algorithm.
Any help would be appreciated.
How about something like:
repl (x,y) xs = map (\i -> if i==x then y else i) xs
Explanation
map is a function that takes a function, applies it to each value in the list, and combines all the return values of that function into a new list.
The \i -> notation is a shortcut for writing the full function definition:
-- Look at value i - if it's the same as x, replace it with y, else do nothing
replacerFunc x y i = if x == y then y else i
then we can rewrite the repl function:
repl (x, y) xs = map (replacerFunc x y) xs
I'm afraid the map function you just have to know - it is relatively easy to see how it works. See the docs:
http://www.haskell.org/hoogle/?hoogle=map
How to write this without map? Now, a good rule of thumb is to get the base case of the recursion out of the way first:
myRep1 _ [] = ???
Now you need a special case if the list element is the one you want to replace. I would recommend a guard for this, as it reads much better than if:
myRep1 (x,y) (z:zs)
| x == z = ???
| otherwise = ???
As this is home work, I left a few blanks for you to fill in :-)
myRepl :: Eq a => (a, a) -> [a] -> [a]
myRepl _ [] = []
myRepl (v, r) (x : xs) | x == v = r : myRepl (v, r) xs
| otherwise = x : myRepl (v, r) xs
Untupled arguments, pointfree, in terms of map:
replaceOccs :: Eq a => a -> a -> [a] -> [a]
replaceOccs v r = map (\ x -> if x == v then r else x)

Haskell: List Comprehension

I have a function that takes in a list, and if there are 2 identical and successive numbers in the list, and if there is a number, x, elsewhere in the list, that is equivalent, then I want to change x to 0 and return the list.
twoAdjThenThirdZero (x:y:xs) = [if x == y && x `elem` xs then 0 else x | x <- xs]
For some reason, it is omitting the first two elements in the list every time I try to run it.
*Main> twoAdjThenThirdZero [2,3,4,1,2,0,2,3,3]
[4,1,2,0,2,0,0]
Also, the above case is doing the opposite of what I would like. I want to keep the two 3's at the end of the list and make the second element, that 3, to be 0. But it was switched around.
*Main> twoAdjThenThirdZero [2,2,3,1,2,4]
[3,1,0,4]
Does anyone know why this is? Thanks in advance!
Try this:
adjToZero = adjToZero' (allDoubles xs)
adjToZero' ds [] = []
adjToZero' ds [x] = [x]
adjToZero' ds (x:y:xs) = if (x/=y) && (x `elem` ds) then 0:(adjToZero' ds (y:xs))
else x:(adjToZero' ds (y:xs))
allDoubles [] = []
allDoubles (x:y:xs) = if (x==y) then x:(allDoubles xs)
else allDoubles (y:xs)
Example:
> adjToZero [1,2,1,1]
[0,2,1,1]
I see multiple problems here. You start by destructuring the parameter list in the function declaration twoAdjThenThirdZero (x:y:xs). If you want to continue to get x and y for each step, you have to recurse. Instead you switch to using a list comprehension, and a duplicate of x. In the list comprehension you go through xs, which is all elements of the function parameter except the first two (x and y).
If you read the list comprehension out loud I think you can figure it out.
"if x equals y and x is an element of xs then zero else x, for every x in xs". But you want it done for every x in x+y+xs! You are also using the name "x" in two ways, both in your destructuring of the function arguments and as a variable in the list comprehension.
EDIT:
Now I see what you mean. You just have to add that explicit recursion to what you have already.
twoAdjThenThirdZero [] = []
twoAdjThenThirdZero [x] = [x]
twoAdjThenThirdZero (x:y:xs)
| x == y && x `elem` xs = x : y : twoAdjThenThirdZero [if z == x then 0 else z | z <- xs]
| otherwise = x : twoAdjThenThirdZero (y:xs)
I hope that makes sense to you, if it doesn't, I'll try to explain it further!
EDIT:
phynfo has posted a slightly simpler version of what I was writing!

haskell list and functional

This is homework that has been driving crazy for the last couple of days.
I got a list that I am applying a function to - pushing each element to the right if the element next to it is smaller then the previous one.
My function to pass over the list once and sort the head of the list:
sortEm lis#(x:y:xs) = if x > y then y: sortEm (x:xs) else lis
sortEm [x] = [x]
sortEm [] = []
myList (x:y:xs) = if x > y then sortEm lis else x:myList(y:xs)
myList [] = []
myList [x] = [x]
But my problem is that once that sortem has finished it returns either an empty list or a list containing one element, how would i design this the functional way?
I was thinking about foldl and some haskell magic to go along with that but currently I am stuck.
Thanks in advance
First of, your sortEm function name is misleading, it doesn't sort its argument list but inserts its head element into its tail. As it happens, there is an insert function already in Data.List module that inserts its first argument into the 2nd, so there's an equivalency
sortEm (x:xs) === Data.List.insert x xs
Now, inserting an item will only get you a sorted list back if you're inserting it into a list that is already sorted. Since empty list is sorted, that's what myList function does that you got in dave4420's answer. That is an "insertion" sort, progressively inserting elements of list into an auxiliary list, initially empty. And that's what the 2nd function does that you got in dave4420 answer:
insertionSort xs = foldr Data.List.insert [] xs
This does "apply sortem" i.e. inserts, "each element" only once. For a list [a,b,c,...,z] it's equivalent to
insert a (insert b (insert c (... (insert z []) ...)))
What you probably meant in your comment, i.e. comparing (and possibly swapping) two neighboring elements "only once", is known as bubble sort. Of course making only one pass through the list won't get it sorted, in a general case:
bubbleOnce xs = foldr g [] xs where
g x [] = [x]
g x xs#(y:ys) | x>y = y:x:ys -- swap x and y in the output
| otherwise = x:xs -- keep x before y in the output
Now, bubbleOnce [4,2,6,1,8] ==> [1,4,2,6,8]. The value that you expected, [2,4,1,6,8], would result from applying the folding function g in an opposite direction, from the left to the right. But that's much less natural to do here with Haskell lists:
bubbleOnce' [] = []
bubbleOnce' (x:xs) = let (z,h)=foldl g (x,id) xs in (h [z]) where
g (x,f) y | x>y = (x, f.(y:)) -- swap x and y in the output
| otherwise = (y, f.(x:)) -- keep x before y in the output
(edit:) see jimmyt's answer for the equivalent, but simple and nice version using straightforward recursion. It is also lazier (less strict) than both the fodlr and foldl versions here.
myList [] = []
myList (x : xs) = sortEm (x : myList xs)
(untested)
Or in terms of a fold:
myList = foldr cons []
where cons x xs = sortEm (x : xs)
(also untested)
-- if..then..else version
sortEM :: Ord a => [a] -> [a]
sortEM (x:y:xs) = if x < y
then x : sortEM (y:xs)
else y : sortEM (x:xs)
sortEM b = b
-- guard version
sortEM_G :: Ord a => [a] -> [a]
sortEM_G (x:y:xs)
| x < y = x : sortEM_G (y:xs)
| otherwise = y : sortEM_G (x:xs)
sortEM_G b = b

Using map to replace elements of a list with (x-y)*(x-y), where y is the initial element

I have a bit of homework to do and I am a complete newbie to Haskell. The question I am having trouble with is to write a function which when given an integer x and a list of integers apply (x-y)*(x-y) to each element in the list and output the new list, with y being each element of the input list.
I have a very rough idea I will have to use the map function but I'm unsure how to go about it.
I have been looking at examples for squaring each element in a list and kind of understand how that works, but how I would implement the (x-y)*(x-y) with y being the current element completely baffles me.
squares :: [Int] -> [Int]
squares (x:xs) = x * x : squares xs
squares [] = []
the exact question I have been set is,
Write a function rela which takes as arguments an integer x and a list of integers. It returns a similar list, but where each element y has been replaced by (x-y)*(x-y), e.g.
Main> rela 2 [3,5,7]
[1,9,25]
I have managed to get it working after reading through some books, but the code I have made misses out the first element in the list. Any explanation why?
equation1 :: Int -> Int -> Int
equation1 x y = (x-y)*(x-y)
rela :: Int -> [Int] -> [Int]
rela x [] =[]
rela x (y:ys) = [ equation1 x y | y <- ys ]
First of all, you should probably create a separate function that does what you want.
e.g.
f x y = (x-y)*(x-y)
Now, every time you create a function in Haskell with multiple parameters, it actually "curries" the function, which means that you get a new function when you apply the first argument to it.
So, you would get a new function by doing this
g = f 5
The expression f 5 is actually a function
And you can apply a number to 'g' and x will always be '5'
So if we want to create a function that takes two parameters, 'x' and 'y', and applies (x-y)*(x-y) to a list where y is the current element, then all we need to do is the following:
f x y = (x-y)*(x-y)
squareDifference x = map (f x) [1,2,3,4]
Which you can use by calling squareDifference 5 or any other number as an argument
A more general version would allow you to pass in a list as well
squareDifference x xs = map (f x) xs
Which you would call by doing squareDifference 3 [1,2,3]
do you understand lambda functions?
map (\val -> the function) xs
is what you need.
currying is even better, but not as simple.
edit:
more conceptual...
map iterates down a list applying a function.
map (+ 3) xs
uses the currying technique mentioned above. you could also:
map (\x -> x + 3) xs
to accomplish the same thing.
Simple example:
rela :: Int -> [Int] -> [Int]
rela x = map (\y -> (x-y)*(x-y))
Or might you want any perversions? -) Here you are with Applicatives:
import Control.Applicative
rela :: Int -> [Int] -> [Int]
rela x = map $ (*) <$> (x-) <*> (x-)
Hello I guess you mean this:
Prelude> let rela n = map (\ x -> (x - n)^2)
Prelude> rela 2 [3,5,7]
[1,9,25]