I've made a function that interchanges the elements of two lists in turn and it works recursively.
change :: [a] -> [a] -> [a]
change [] ys = ys
change xs [] = xs
change (x:xs) (y:ys) = x : y : change xs ys
Now this works fine but I am having difficulty with turning it into list comprehension. I want to do that to practice Haskell and it was just one of the questions I found.
You could do something like this:
change xs ys = [v | vs <- transpose [xs, ys], v <- vs]
But I wouldn't. That's a very confusing way to write this function -- and anyway, you haven't really converted manual recursion into a list comprehension this way, you've just shoved the manual recursion into transpose.
I've tried to use a function that calculate the reverse of a list. So I can use it in other function that will be the palindrome function, but always I get an error.
The first one works.
This is the code:
rev :: [a] -> [a]
rev [] = []
rev (x:xs) = rev xs ++ [x]
palindrome :: [a] -> Bool
palindrome [] = True
palindrome (x:xs) = if xs == rev (x:xs) then True else False
I have to mention that I have to do it with that signature: [a] -> Bool
Someday I will muster the energy to put together a megaquestion to address two common beginner list mistakes: thinking that [x] matches a list of any length, and thinking that any function on lists must have [] and x:xs patterns. This question is an example of the latter. When you do the same thing regardless of list length, you don't need multiple patterns! Just palindrome xs = ... is fine. Try writing your palindrome function again with this in mind; your bug will be fixed as a side effect.
I am sorry for not being able to really formulate this question well in the title; I have already asked the same question about triples and have decided to opt for a list after all, so here is the explanation. Thank you for the patience and great help received here!
I need to create a function that is capable of doing the following, yet am quite a newby to Haskell and find myself in need of passing states that is just not in the functional paradigm (nor do I want a semi imperative solution, I just want to know how to do it the functional way). The functionality is as follows:
specialFunc :: [a] -> a -> [[a]]
specialFunc [1,2,3] 0
=> [[0,2,3],[1,0,3],[1,2,0]]
I am trying to create the function by mapping over the list supplied as an argument, but find myself at a loss when I try and figure out how to replace a specific value, add the resulting list to the results and continue working with the next item but with the original list (if that makes sense). Any help is definitely welcome, thank you!
You can define this in a recursive way. If the list is empty (1), then you return an empty list, so [] maps to []. If the list is non-empty (2), then we generate a list where the first item is the tail of the non-empty list, prepended with the value, and we recurse on the tail of the list, and need to prepend the head of the list.
So we can define a function that looks like:
specialFunc :: [a] -> a -> [[a]]
specialFunc xs x = go xs
where go [] = … -- (1)
go (h:hs) = … -- (2)
You can make use of map :: (a -> b) -> [a] -> [b] to prepend the value h to the lists you generate through recursion.
The solution, with many credits to #WillemVanOnsem:
specialFunc :: [a] -> a -> [[a]]
specialFunc xs x = go xs
where go [] = []
go (h:hs) = (x:hs): map (h:) (go hs)
Just to give you another idea of how this could be done, you might turn on the ParallelListComp extension and zip up the result of inits and tails appropriately:
{-# Language ParallelListComp #-}
import Data.List
specialFunc xs x = [pre ++ [x] ++ suf | pre <- inits xs | _:suf <- tails xs]
The same idea can also be done without an extension, of course, though I think it's not quite as pretty:
import Data.List
specialFunc xs x = zipWith (\pre suf -> pre ++ [x] ++ suf) (inits xs) (tail (tails xs))
I need a function to double every other number in a list. This does the trick:
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther [] = []
doubleEveryOther (x:[]) = [x]
doubleEveryOther (x:(y:zs)) = x : 2 * y : doubleEveryOther zs
However, the catch is that I need to double every other number starting from the right - so if the length of the list is even, the first one will be doubled, etc.
I understand that in Haskell it's tricky to operate on lists backwards, so my plan was to reverse the list, apply my function, then output the reverse again. I have a reverseList function:
reverseList :: [Integer] -> [Integer]
reverseList [] = []
reverseList xs = last xs : reverseList (init xs)
But I'm not quite sure how to implant it inside my original function. I got to something like this:
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther [] = []
doubleEveryOther (x:[]) = [x]
doubleEveryOther (x:(y:zs)) =
| rev_list = reverseList (x:(y:zs))
| rev_list = [2 * x, y] ++ doubleEveryOther zs
I'm not exactly sure of the syntax of a function that includes intermediate values like this.
In case it's relevant, this is for Exercise 2 in CIS 194 HW 1.
This is a very simple combination of the two functions you've already created:
doubleEveryOtherFromRight = reverseList . doubleEveryOther . reverseList
Note that your reverseList is actually already defined in the standard Prelude as reverse. so you didn't need to define it yourself.
I'm aware that the above solution isn't very efficient, because both uses of reverse need to pass through the entire list. I'll leave it to others to suggest more efficient versions, but hopefully this illustrates the power of function composition to build more complex computations out of simpler ones.
As Lorenzo points out, you can make one pass to determine if the list has an odd or even length, then a second pass to actually construct the new list. It might be simpler, though, to separate the two tasks.
doubleFromRight ls = zipWith ($) (cycle fs) ls -- [f0 ls0, f1 ls1, f2 ls2, ...]
where fs = if odd (length ls)
then [(*2), id]
else [id, (*2)]
So how does this work? First, we observe that to create the final result, we need to apply one of two function (id or (*2)) to each element of ls. zipWith can do that if we have a list of appropriate functions. The interesting part of its definition is basically
zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys
When f is ($), we're just applying a function from one list to the corresponding element in the other list.
We want to zip ls with an infinite alternating list of id and (*2). The question is, which function should that list start with? It should always end with (*2), so the starting item is determined by the length of ls. An odd-length requires us to start with (*2); an even one, id.
Most of the other solutions show you how to either use the building blocks you already have or building blocks available in the standard library to build your function. I think it's also instructive to see how you might build it from scratch, so in this answer I discuss one idea for that.
Here's the plan: we're going to walk all the way to the end of the list, then walk back to the front. We'll build our new list during our walk back from the end. The way we'll build it as we walk back is by alternating between (multiplicative) factors of 1 and 2, multiplying our current element by our current factor and then swapping factors for the next step. At the end we'll return both the final factor and the new list. So:
doubleFromRight_ :: Num a => [a] -> (a, [a])
doubleFromRight_ [] = (1, [])
doubleFromRight_ (x:xs) =
-- not at the end yet, keep walking
let (factor, xs') = doubleFromRight_ xs
-- on our way back to the front now
in (3-factor, factor*x:xs')
If you like, you can write a small wrapper that throws away the factor at the end.
doubleFromRight :: Num a => [a] -> [a]
doubleFromRight = snd . doubleFromRight_
In ghci:
> doubleFromRight [1..5]
[1,4,3,8,5]
> doubleFromRight [1..6]
[2,2,6,4,10,6]
Modern practice would be to hide the helper function doubleFromRight_ inside a where block in doubleFromRight; and since the slightly modified name doesn't actually tell you anything new, we'll use the community standard name internally. Those two changes might land you here:
doubleFromRight :: Num a => [a] -> [a]
doubleFromRight = snd . go where
go [] = (1, [])
go (x:xs) = let (factor, xs') = go xs in (3-factor, factor*x:xs')
An advanced Haskeller might then notice that go fits into the shape of a fold and write this:
doubleFromRight :: Num a => [a] -> [a]
doubleFromRight = snd . foldr (\x (factor, xs) -> (3-factor, factor*x:xs)) (1,[])
But I think it's perfectly fine in this case to stop one step earlier with the explicit recursion; it may even be more readable in this case!
If we really want to avoid calculating the length, we can define
doubleFromRight :: Num a => [a] -> [a]
doubleFromRight xs = zipWith ($)
(foldl' (\a _ -> drop 1 a) (cycle [(2*), id]) xs)
xs
This pairs up the input list with the cycled infinite list of functions, [(*2), id, (*2), id, .... ]. then it skips along them both. when the first list is finished, the second is in the appropriate state to be - again - applied, pairwise, - on the second! This time, for real.
So in effect it does measure the length (of course), it just doesn't count in integers but in the list elements so to speak.
If the length of the list is even, the first element will be doubled, otherwise the second, as you've specified in the question:
> doubleFromRight [1..4]
[2,2,6,4]
> doubleFromRight [1..5]
[1,4,3,8,5]
The foldl' function processes the list left-to-right. Its type is
foldl' :: (b -> a -> b) -> b -> [a] -> b
-- reducer_func acc xs result
Whenever you have to work on consecutive terms in a list, zip with a list comprehension is an easy way to go. It takes two lists and returns a list of tuples, so you can either zip the list with its tail or make it indexed. What i mean is
doubleFromRight :: [Int] -> [Int]
doubleFromRight ls = [if (odd i == oddness) then 2*x else x | (i,x) <- zip [1..] ls]
where
oddness = odd . length $ ls
This way you count every element, starting from 1 and if the index has the same parity as the last element in the list (both odd or both even), then you double the element, else you leave it as is.
I am not 100% sure this is more efficient, though, if anyone could point it out in the comments that would be great
I have a function which was written in list comprehension. As a learning I decided to try to convert this function into a functional application using map, zip, fold, etc. I am having a really hard time converting this particular one.
It might seem unreasonable for what it is doing, but it is part of a bigger function and I want to get this piece working first.
combination :: Int -> [a] -> [([a],[a])]
combination 0 xs = [([],xs)]
combination n (x:xs) = [ (x:ys,zs) | (ys,zs) <- combination (n-1) xs ]
It's just a map:
combination :: Int -> [a] -> [([a],[a])]
combination 0 xs = [([],xs)]
combination n (x:xs) = map (\(ys, zs) -> (x:ys,zs)) (combination (n-1) xs)