I made these two haskell functions,
cut :: Int -> [a] -> (Error ([a],[a]))
cut _ [] = Ok([],[])
cut n xs | n>0 && n < length xs = Ok(take n xs, drop n xs)
| n > length xs = error("Fail")
mix :: [a] -> [a] -> [a]
mix xs [] = xs
mix [] ys = ys
mix (x:xs) (y:ys) = x:y:mix xs ys
An now wish to make anouther function in which i can use both of these,
this is what i have;
doboth :: [Int] -> [a] -> Error [a]
doboth (x:xs) list = mix((cut x list)) then send xs back to doboth recursivly for the next x elemet of the list.
The idea of this function is to cut a list and then mix the two lists, it gets the cut points from the do both list of ints...
ANy ideas?
Since cut returns not a list, you need to pattern match a bit:
case cut x list of
Ok (as, bs) -> mix ... ... -- and so forth
Shouldn't doboth return Error [[a]]?
Maybe you should use a standard type like Maybe or Either instead Error.
If I understand what you want correctly, then doboth would be something like
doboth xs list = mapM (\ x -> mix (cut x list)) xs
Assuming you've made Error into a monad (which Maybe and Either already are).
There are several questions you have to ask yourself:
Does cut have to return an Error value? Or can you come up with a reasonable definition that works for all inputs. For example, tail doesn't work for all inputs, whereas take does. Investigate take and see how it handles exceptional inputs. This might lead you to a better definition of cut. The reason this is important is that functions that return uniform results for all values are generally much easier to work with.
What do you expect doboth to do if the result of the cut is an error?
Does doboth operate on elements of a list independently? Or are the result dependent on earlier computations? The first is map like, the second fold like. You want to perform a cut and mix for each value in the [Int] input, but should the input to cut be the original list, or the list from the previous step?
Given that you have computed one step of doboth, what should the next step of doboth look like? Try writing out the code that would do two, or even three, steps of doboth at once.
What is the value of doboth if the [Int] argument is empty?
Related
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
Assume the following (non-functioning) code, that takes a predicate such as (==2) and a list of integers, and drops only the last element of the list that satisfies the predicate:
cutLast :: (a -> Bool) -> [Int] -> [Int]
cutLast a [] = []
cutLast pred (as:a)
| (pred) a == False = (cutLast pred as):a
| otherwise = as
This code does not work, so clearly lists cannot be iterated through in reverse like this. How could I implement this idea? I'm not 100% sure if the code is otherwise correct - but hopefully it gets the idea across.
Borrowing heavily from myself: the problem with this sort of question is that you don't know which element to remove until you get to the end of the list. Once we observe this, the most straightforward thing to do is traverse the list one way then back using foldr (the second traversal comes from the fact foldr is not tail-recursive).
The cleanest solution I can think of is to rebuild the list on the way back up, dropping the first element.
cutLast :: Eq a => (a -> Bool) -> [a] -> Either [a] [a]
cutLast f = foldr go (Left [])
where
go x (Right xs) = Right (x:xs)
go x (Left xs) | f x = Right xs
| otherwise = Left (x:xs)
The return type is Either to differentiate between not found anything to drop from the list (Left), and having encountered and dropped the last satisfying element from the list (Right). Of course, if you don't care about whether you dropped or didn't drop an element, you can drop that information:
cutLast' f = either id id . cutLast f
Following the discussion of speed in the comments, I tried swapping out Either [a] [a] for (Bool,[a]). Without any further tweaking, this is (as #dfeuer predicted) consistently a bit slower (on the order of 10%).
Using irrefutable patterns on the tuple, we can indeed avoid forcing the whole output (as per #chi's suggestion), which makes this much faster for lazily querying the output. This is the code for that:
cutLast' :: Eq a => (a -> Bool) -> [a] -> (Bool,[a])
cutLast' f = foldr go (False,[])
where
go x ~(b,xs) | not (f x) = (b,x:xs)
| not b = (False,x:xs)
| otherwise = (True,xs)
However, this is 2 to 3 times slower than either of the other two versions (that don't use irrefutable patterns) when forced to normal form.
One simple (but less efficient) solution is to implement cutFirst in a similar fashion to filter, then reverse the input to and output from that function.
cutLast pred = reverse . cutFirst . reverse
where cutFirst [] = []
cutFirst (x:xs) | pred x = xs
| otherwise = x : cutFirst xs
I'm relatively new to Haskell and I'm struggling to figure out a way to implement Haskell's span function. However, my problem is more general than that in that I don't know how to make a function return a list of lists or list of tuples containing the elements I want. My problem with a list of lists such as:
[[1],[2]]
is that I can't make the function add an element to the first list in the list of lists. I only know how to append another list to the list of lists.
In short, if you explain to me how to implement the span function, this all should hopefully come clear to me.
So I think what you're saying is that you know how to recursively append to a list by doing something like
foobar :: [x] -> [y]
foobar ( []) = []
foobar (x:xs) = {- ...stuff... -} : foobar xs
but you have no idea how to do that with two lists:
foobar :: [x] -> ([y], [z])
foobar (x:xs) = ???
In general, when the result isn't a list, but something that contains a list, you end up doing something like this:
foobar :: [x] -> ([y], [z])
foobar (x:xs) =
let
y = {- whatever -}
z = {- whatever -}
(ys, zs) = foobar xs -- The recursive call
in (y:ys, z:zs)
The same applies if, say, the result is a monadic action
foobar :: [x] -> IO [y]
foobar (x:xs) = do
y <- {- whatever -}
ys <- foobar xs
return (y:ys)
Note that this forces the function to not be lazy.
The general pattern I think you'll want to use here is the following:
span :: (a -> Bool) -> [a] -> ([a], [a])
span pred [] = ([], [])
span pred (x:xs) = if pred x then _ else _ -- fill in the blanks
where (prefix', suffix') = span pred xs
There are two non-obvious things there. First, note the pattern match in the where condition. This means that we're:
Calling span pred xs, which produces a pair of lists;
Pattern matching on this pair;
Naming the first and second element of the pair prefix' and suffix' respectively.
I suspect that step #2, the pattern match on the result of the recursive call, is something you might not have understood.
The second non-obvious thing is recursion. It's a tricky thing because, counterintutively, to solve a problem with recursion you need to assume that you've already solved it, but for the "wrong" argument--a tough step to picture yourself taking if you haven't solved it yet! But the trick is this:
Imagine you've actually already solved the problem, but for the tail of the list. That's what the prefix' and suffix' variables contain: a correct solution but for the wrong list--the tail of the one you're actually trying to solve for.
Given that (non)solution, how could you reuse it to arrive at a correct solution for your problem?
What is the fastest way to get the last element of a list in Haskell. Also in next iteration, I want to remove first and last element of the list. What is the most elegant way to do it? I am trying list comprehension, but that does not look very efficient!
You can use the last function to get the last element of a list.
As for how to remove the first and last elements, you could use (init . tail), but I don't know how efficient that is.
I think this image from Learn You A Haskell shows the list functions fairly well:
last and init will do the job just fine for a one-off. However they are both O(n), so if you need to manipulate both ends of a list often, as you seem to imply, you might want to consider using Data.Sequence instead, which supports O(1) insertion and removal of items at both ends.
I'll post the Prelude implementation since it hasn't been posted yet:
listLast :: [a] -> a
listLast [x] = x --base case is when there's just one element remaining
listLast (_:xs) = listLast xs --if there's anything in the head, continue until there's one element left
listLast [] = error "Can't do last of an empty list!"
Note that I changed the function name to listLast so that it can be run without conflicting with normal Prelude. You could, of course, do import Prelude hiding(last).
To remove first and last:
take (len(l)-2) (drop 1 l)
or maybe
init (drop 1 l)
This also results in almost optimal code.
This answer focuses on dealing with weird conditions (like empty lists) in a maximally flexible way, and on building up bigger functions from smaller ones using some library functions. It's not the best answer for someone first learning about lists, but rather a couple steps past that.
For the following, you will need
import Control.Monad ((>=>))
and you will need to either use GHC 7.10 and import Data.List (uncons) or define
uncons :: [a] -> Maybe (a, [a])
uncons [] = Nothing
uncons (x:xs) = Just (x,xs)
You can write a safe form of init like this:
init' :: [x] -> Maybe [x]
init' = foldr go Nothing
where
go x mxs = Just (maybe [] (x:) mxs)
A version of tail can be written
tail' :: [a] -> Maybe [a]
tail' = fmap snd . uncons
So then you can get a maybefied
trim' :: [a] -> Maybe [a]
trim' = init' >=> tail'
The >=> is a sort of backwards monadic composition. init' >=> tail' is a function that applies init' to its argument to get a Maybe [a]. If it gets Nothing, it returns that. If it gets Just xs, it applies tail' to xs and returns that.
From this, you can easily make a trimmer that trims lists with 0, 1, or 2 elements down to empty lists:
trim :: [a] -> [a]
trim = maybe [] id . trim'
last' :: [a] -> a
last' ys = foldl1 (\_ -> \x -> x) ys
It is O(n), just like the built in library function list.
(head.reverse) [1..100]
Is an alternative to last to get the last element.
drop 1 (take (length [1..100] - 1) [1..100])
removes the first and last list element. The source for drop and take look like it might be faster than (init . tail).
(reverse.drop 1) ((reverse.drop 1) [1..100])
is another variant. But I guess slower because of the double reversal.