What to use instead of explicit recursion in Haskell? - haskell

Write a function that doubles other number beginning with the 2nd number from the right:
Example:
doubleEveryOther [8,7,6,5]
=> [16,7,12,5]
doubleEveryOther [1,2,3]
=> [1,4,3]
O(n) solution:
doubleEveryOther :: Num a => [a] -> [a]
doubleEveryOther xs0 =
let (_,r) = deo xs0
deo xs1 = case xs1 of
[] -> (False, [])
(x:xs) -> let (b, xs') = deo xs in ((not b), (if b then 2*x else x) : xs')
in r
The use above of explicit recursion is generally considered poor Haskell style (e.g., use fold*, scan, etc where possible).
QUESTIONS
what Haskell library functions cover the above case?
what would be a more concise/idiomatic Haskell solution that is still O(n)?
is there a name for the above type of recursion (where we use the value from a deeper recursion to make a decision the next level up)?

You can use foldr to do this kind of recursion from the right:
doubleEveryOther = snd . foldr go (False, [])
where go x (b, xs) = (not b, (if b then 2*x else x) : xs)

Another way to define this function by using standard library functions:
doubleEveryOther ls = reverse $ zipWith (*) (cycle [1,2]) (reverse ls)
Or in pointfree style
doubleEveryOther = reverse . zipWith (*) (cycle [1,2]) . reverse

Lots of useful answers here, but no one yet mentioned the rarely seen function mapAccumR from Data.List which fits this particular use case almost perfectly:
doubleEveryOther :: Num a => [a] -> [a]
doubleEveryOther = snd . mapAccumR step False
where
step False x = (True, x)
step True x = (False, 2*x)

As to question 1 and 2, with lens you can define the function in a declarative manner:
import Control.Lens
doubleEveryOther :: Num a => [a] -> [a]
doubleEveryOther = reversed . traversed . indices odd *~ 2
Operationally, this involves reversing the list, then modifying, then reversing again, but of course it's still O(N) with any constant number of reversals.

An alternative is to use the
lens package.
This allows you to avoid explicit recursion and remain very flexible on what data structures you can operate on.
You can use the elements traversal. It takes a Int -> Bool function to decide what indices to act on.
Double even indices or odd indices.
> over (elements even) (*2) [8,7,6,5]
[16,7,12,5]
> over (elements odd) (*2) [8,7,6,5]
[8,14,6,10]
Or double every third element:
> over (elements (\n -> mod n 3 == 0)) (*2) [8,7,6,5]
[16,7,6,10]
Not just lists
This technique will work for any datatype that has a Traversable instance.
For example take the standard tree datatype for the
containers.
> import Data.Tree
> let tree = Node 1 [Node 2 [Node 3 [], Node 4 []], Node 5 [Node 6 []]]
> let prettyTree = putStrLn . drawTree . fmap show
> prettyTree tree
1
|
+- 2
| |
| +- 3
| |
| `- 4
|
`- 5
|
`- 6
> prettyTree $ over (elements even) (*2) tree
2 -- 1
| -- |
+- 2 -- +- 2
| | -- | |
| +- 6 -- | +- 3
| | -- | |
| `- 4 -- | `- 4
| -- |
`- 10 -- `- 5
| -- |
`- 6 -- `- 6
Your questions.
The lens package has a number of functions that help with handling recursion with out being explicit.
The lens is concise, though some do not yet considered it idiomatic. I have not tested the bigO of the above functions. My understanding is that it will depend on the bigO of the traversable instance for the datatype you are using.
The list instance in the Traversable module looks straightforward and should meet your expectations.:
instance Traversable [] where
{-# INLINE traverse #-} -- so that traverse can fuse
traverse f = Prelude.foldr cons_f (pure [])
where cons_f x ys = (:) <$> f x <*> ys
I am not sure what you are asking for here.

You can use map as well:
Prelude> let f ns = map (\(a,b) -> if (even (length ns) && even b) || (odd (length ns) && odd b) then a else a * 2) $ zip ns [1..]
Prelude> f [8,7,6,5]
[16,7,12,5]
Prelude> f [8,7,6]
[8,14,6]

My solution using mutual recursions
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther xs
| even n = doubleOdd xs
| otherwise = doubleEven xs
where n = length xs
-- | use mutual recursion
doubleEven :: Num a => [a] -> [a]
doubleEven (x:xs) = x : doubleOdd xs
doubleEven [] = []
doubleOdd :: Num a => [a] -> [a]
doubleOdd (x:xs) = (2*x) : doubleEven xs
doubleOdd [] = []

For the sake of completeness, here is your solution encoded as a recursion-schemes zygomorphism, as anticipated by András Kovács's remark:
{-# LANGUAGE LambdaCase #-}
import Data.Functor.Foldable
doubleEveryOther :: Num a => [a] -> [a]
doubleEveryOther = zygo flagAlg emitAlg
where
flagAlg = \case
Nil -> False
Cons _ b -> not b
emitAlg = \case
Nil -> []
Cons x (b, xs) -> (if b then 2*x else x) : xs

Related

Split a list into non-empty sub-lists in Haskell

I have to split the given list into non-empty sub-lists each of which
is either in strictly ascending order, in strictly descending order, or contains all equal elements. For example, [5,6,7,2,1,1,1] should become [[5,6,7],[2,1],[1,1]].
Here is what I have done so far:
splitSort :: Ord a => [a] -> [[a]]
splitSort ns = foldr k [] ns
where
k a [] = [[a]]
k a ns'#(y:ys) | a <= head y = (a:y):ys
| otherwise = [a]:ns'
I think I am quite close but when I use it it outputs [[5,6,7],[2],[1,1,1]] instead of [[5,6,7],[2,1],[1,1]].
Here is a kinda ugly solution, with three reverse in one line of code :).
addElement :: Ord a => a -> [[a]] -> [[a]]
addElement a [] = [[a]]
addElement a (x:xss) = case x of
(x1:x2:xs)
| any (check a x1 x2) [(==),(<),(>)] -> (a:x1:x2:xs):xss
| otherwise -> [a]:(x:xss)
_ -> (a:x):xss
where
check x1 x2 x3 op = (x1 `op` x2) && (x2 `op` x3)
splitSort xs = reverse $ map reverse $ foldr addElement [] (reverse xs)
You can possibly get rid of all the reversing if you modify addElement a bit.
EDIT:
Here is a less reversing version (even works for infinite lists):
splitSort2 [] = []
splitSort2 [x] = [[x]]
splitSort2 (x:y:xys) = (x:y:map snd here):splitSort2 (map snd later)
where
(here,later) = span ((==c) . uncurry compare) (zip (y:xys) xys)
c = compare x y
EDIT 2:
Finally, here is a solution based on a single decorating/undecorating, that avoids comparing any two values more than once and is probably a lot more efficient.
splitSort xs = go (decorate xs) where
decorate :: Ord a => [a] -> [(Ordering,a)]
decorate xs = zipWith (\x y -> (compare x y,y)) (undefined:xs) xs
go :: [(Ordering,a)] -> [[a]]
go ((_,x):(c,y):xys) = let (here, later) = span ((==c) . fst) xys in
(x : y : map snd here) : go later
go xs = map (return . snd) xs -- Deal with both base cases
Every ordered prefix is already in some order, and you don't care in which, as long as it is the longest:
import Data.List (group, unfoldr)
foo :: Ord t => [t] -> [[t]]
foo = unfoldr f
where
f [] = Nothing
f [x] = Just ([x], [])
f xs = Just $ splitAt (length g + 1) xs
where
(g : _) = group $ zipWith compare xs (tail xs)
length can be fused in to make the splitAt count in unary essentially, and thus not be as strict (unnecessarily, as Jonas Duregård rightly commented):
....
f xs = Just $ foldr c z g xs
where
(g : _) = group $ zipWith compare xs (tail xs)
c _ r (x:xs) = let { (a,b) = r xs } in (x:a, b)
z (x:xs) = ([x], xs)
The initial try turned out to be lengthy probably inefficient but i will keep it striked for the sake of integrity with the comments. You best just skip to the end for the answer.
Nice question... but turns out to be a little hard candy. My approach is in segments, those of each i will explain;
import Data.List (groupBy)
splitSort :: Ord a => [a] -> [[a]]
splitSort (x:xs) = (:) <$> (x :) . head <*> tail $ interim
where
pattern = zipWith compare <$> init <*> tail
tuples = zipWith (,) <$> tail <*> pattern
groups = groupBy (\p c -> snd p == snd c) . tuples $ (x:xs)
interim = groups >>= return . map fst
*Main> splitSort [5,6,7,2,1,1,1]
[[5,6,7],[2,1],[1,1]]
The pattern function (zipWith compare <$> init <*> tail) is of type Ord a => [a] -> [Ordering] when fed with [5,6,7,2,1,1,1] compares the init of it by the tail of it by zipWith. So the result would be [LT,LT,GT,GT,EQ,EQ]. This is the pattern we need.
The tuples function will take the tail of our list and will tuple up it's elements with the corresponding elements from the result of pattern. So we will end up with something like [(6,LT),(7,LT),(2,GT),(1,GT),(1,EQ),(1,EQ)].
The groups function utilizes Data.List.groupBy over the second items of the tuples and generates the required sublists such as [[(6,LT),(7,LT)],[(2,GT),(1,GT)],[(1,EQ),(1,EQ)]]
Interim is where we monadically get rid of the Ordering type values and tuples. The result of interim is [[6,7],[2,1],[1,1]].
Finally at the main function body (:) <$> (x :) . head <*> tail $ interim appends the first item of our list (x) to the sublist at head (it has to be there whatever the case) and gloriously present the solution.
Edit: So investigating the [0,1,0,1] resulting [[0,1],[0],[1]] problem that #Jonas Duregård discovered, we can conclude that in the result there shall be no sub lists with a length of 1 except for the last one when singled out. I mean for an input like [0,1,0,1,0,1,0] the above code produces [[0,1],[0],[1],[0],[1],[0]] while it should [[0,1],[0,1],[0,1],[0]]. So I believe adding a squeeze function at the very last stage should correct the logic.
import Data.List (groupBy)
splitSort :: Ord a => [a] -> [[a]]
splitSort [] = []
splitSort [x] = [[x]]
splitSort (x:xs) = squeeze $ (:) <$> (x :) . head <*> tail $ interim
where
pattern = zipWith compare <$> init <*> tail
tuples = zipWith (,) <$> tail <*> pattern
groups = groupBy (\p c -> snd p == snd c) $ tuples (x:xs)
interim = groups >>= return . map fst
squeeze [] = []
squeeze [y] = [y]
squeeze ([n]:[m]:ys) = [n,m] : squeeze ys
squeeze ([n]:(m1:m2:ms):ys) | compare n m1 == compare m1 m2 = (n:m1:m2:ms) : squeeze ys
| otherwise = [n] : (m1:m2:ms) : squeeze ys
squeeze (y:ys) = y : squeeze s
*Main> splitSort [0,1, 0, 1, 0, 1, 0]
[[0,1],[0,1],[0,1],[0]]
*Main> splitSort [5,6,7,2,1,1,1]
[[5,6,7],[2,1],[1,1]]
*Main> splitSort [0,0,1,0,-1]
[[0,0],[1,0,-1]]
Yes; as you will also agree the code has turned out to be a little too lengthy and possibly not so efficient.
The Answer: I have to trust the back of my head when it keeps telling me i am not on the right track. Sometimes, like in this case, the problem reduces down to a single if then else instruction, much simpler than i had initially anticipated.
runner :: Ord a => Maybe Ordering -> [a] -> [[a]]
runner _ [] = []
runner _ [p] = [[p]]
runner mo (p:q:rs) = let mo' = Just (compare p q)
(s:ss) = runner mo' (q:rs)
in if mo == mo' || mo == Nothing then (p:s):ss
else [p] : runner Nothing (q:rs)
splitSort :: Ord a => [a] -> [[a]]
splitSort = runner Nothing
My test cases
*Main> splitSort [0,1, 0, 1, 0, 1, 0]
[[0,1],[0,1],[0,1],[0]]
*Main> splitSort [5,6,7,2,1,1,1]
[[5,6,7],[2,1],[1,1]]
*Main> splitSort [0,0,1,0,-1]
[[0,0],[1,0,-1]]
*Main> splitSort [1,2,3,5,2,0,0,0,-1,-1,0]
[[1,2,3,5],[2,0],[0,0],[-1,-1],[0]]
For this solution I am making the assumption that you want the "longest rally". By that I mean:
splitSort [0, 1, 0, 1] = [[0,1], [0,1]] -- This is OK
splitSort [0, 1, 0, 1] = [[0,1], [0], [1]] -- This is not OK despite of fitting your requirements
Essentially, There are two pieces:
Firstly, split the list in two parts: (a, b). Part a is the longest rally considering the order of the two first elements. Part b is the rest of the list.
Secondly, apply splitSort on b and put all list into one list of list
Taking the longest rally is surprisingly messy but straight. Given the list x:y:xs: by construction x and y will belong to the rally. The elements in xs belonging to the rally depends on whether or not they follow the Ordering of x and y. To check this point, you zip every element with the Ordering is has compared against its previous element and split the list when the Ordering changes. (edge cases are pattern matched) In code:
import Data.List
import Data.Function
-- This function split the list in two (Longest Rally, Rest of the list)
splitSort' :: Ord a => [a] -> ([a], [a])
splitSort' [] = ([], [])
splitSort' (x:[]) = ([x],[])
splitSort' l#(x:y:xs) = case span ( (o ==) . snd) $ zip (y:xs) relativeOrder of
(f, s) -> (x:map fst f, map fst s)
where relativeOrder = zipWith compare (y:xs) l
o = compare y x
-- This applies the previous recursively
splitSort :: Ord a => [a] -> [[a]]
splitSort [] = []
splitSort (x:[]) = [[x]]
splitSort (x:y:[]) = [[x,y]]
splitSort l#(x:y:xs) = fst sl:splitSort (snd sl)
where sl = splitSort' l
I wonder whether this question can be solve using foldr if splits and groups a list from
[5,6,7,2,1,1,1]
to
[[5,6,7],[2,1],[1,1]]
instead of
[[5,6,7],[2],[1,1,1]]
The problem is in each step of foldr, we only know the sorted sub-list on right-hand side and a number to be processed. e.g. after read [1,1] of [5,6,7,2,1,1,1] and next step, we have
1, [[1, 1]]
There are no enough information to determine whether make a new group of 1 or group 1 to [[1,1]]
And therefore, we may construct required sorted sub-lists by reading elements of list from left to right, and why foldl to be used. Here is a solution without optimization of speed.
EDIT:
As the problems that #Jonas Duregård pointed out on comment, some redundant code has been removed, and beware that it is not a efficient solution.
splitSort::Ord a=>[a]->[[a]]
splitSort numList = foldl step [] numList
where step [] n = [[n]]
step sublists n = groupSublist (init sublists) (last sublists) n
groupSublist sublists [n1] n2 = sublists ++ [[n1, n2]]
groupSublist sublists sortedList#(n1:n2:ns) n3
| isEqual n1 n2 = groupIf (isEqual n2 n3) sortedList n3
| isAscen n1 n2 = groupIfNull isAscen sortedList n3
| isDesce n1 n2 = groupIfNull isDesce sortedList n3
| otherwise = mkNewGroup sortedList n3
where groupIfNull check sublist#(n1:n2:ns) n3
| null ns = groupIf (check n2 n3) [n1, n2] n3
| otherwise = groupIf (check (last ns) n3) sublist n3
groupIf isGroup | isGroup = addToGroup
| otherwise = mkNewGroup
addToGroup gp n = sublists ++ [(gp ++ [n])]
mkNewGroup gp n = sublists ++ [gp] ++ [[n]]
isEqual x y = x == y
isAscen x y = x < y
isDesce x y = x > y
My initial thought looks like:
ordruns :: Ord a => [a] -> [[a]]
ordruns = foldr extend []
where
extend a [ ] = [ [a] ]
extend a ( [b] : runs) = [a,b] : runs
extend a (run#(b:c:etc) : runs)
| compare a b == compare b c = (a:run) : runs
| otherwise = [a] : run : runs
This eagerly fills from the right, while maintaining the Ordering in all neighbouring pairs for each sublist. Thus only the first result can end up with a single item in it.
The thought process is this: an Ordering describes the three types of subsequence we're looking for: ascending LT, equal EQ or descending GT. Keeping it the same every time we add on another item means it will match throughout the subsequence. So we know we need to start a new run whenever the Ordering does not match. Furthermore, it's impossible to compare 0 or 1 items, so every run we create contains at least 1 and if there's only 1 we do add the new item.
We could add more rules, such as a preference for filling left or right. A reasonable optimization is to store the ordering for a sequence instead of comparing the leading two items twice per item. And we could also use more expressive types. I also think this version is inefficient (and inapplicable to infinite lists) due to the way it collects from the right; that was mostly so I could use cons (:) to build the lists.
Second thought: I could collect the lists from the left using plain recursion.
ordruns :: Ord a => [a] -> [[a]]
ordruns [] = []
ordruns [a] = [[a]]
ordruns (a1:a2:as) = run:runs
where
runs = ordruns rest
order = compare a1 a2
run = a1:a2:runcontinuation
(runcontinuation, rest) = collectrun a2 order as
collectrun _ _ [] = ([], [])
collectrun last order (a:as)
| order == compare last a =
let (more,rest) = collectrun a order as
in (a:more, rest)
| otherwise = ([], a:as)
More exercises. What if we build the list of comparisons just once, for use in grouping?
import Data.List
ordruns3 [] = []
ordruns3 [a] = [[a]]
ordruns3 xs = unfoldr collectrun marked
where
pairOrder = zipWith compare xs (tail xs)
marked = zip (head pairOrder : pairOrder) xs
collectrun [] = Nothing
collectrun ((o,x):xs) = Just (x:map snd markedgroup, rest)
where (markedgroup, rest) = span ((o==).fst) xs
And then there's the part where there's a groupBy :: (a -> a -> Bool) -> [a] -> [[a]] but no groupOn :: Eq b => (a -> b) -> [a] -> [[a]]. We can use a wrapper type to handle that.
import Data.List
data Grouped t = Grouped Ordering t
instance Eq (Grouped t) where
(Grouped o1 _) == (Grouped o2 _) = o1 == o2
ordruns4 [] = []
ordruns4 [a] = [[a]]
ordruns4 xs = unmarked
where
pairOrder = zipWith compare xs (tail xs)
marked = group $ zipWith Grouped (head pairOrder : pairOrder) xs
unmarked = map (map (\(Grouped _ t) -> t)) marked
Of course, the wrapper type's test can be converted into a function to use groupBy instead:
import Data.List
ordruns5 [] = []
ordruns5 [a] = [[a]]
ordruns5 xs = map (map snd) marked
where
pairOrder = zipWith compare xs (tail xs)
marked = groupBy (\a b -> fst a == fst b) $
zip (head pairOrder : pairOrder) xs
These marking versions arrive at the same decoration concept Jonas Duregård applied.

Compiler cannot decide the type of the return value of `take` function

I'm trying to solve the 99 problems in Haskell, and for the 4th question, I have first tried such a solution
myLength :: [a] -> Int
myLength [] = 0
myLength ys = go 1 ys
where
go :: Int -> [a] -> Int
go n xs
| ( (take n xs) == (take (n+1) xs) ) = n
| otherwise = go (n+1) xs
However, the compiler gives the error:
Problem4.hs:10:8: error:
• No instance for (Eq a1) arising from a use of ‘==’
Possible fix:
add (Eq a1) to the context of
the type signature for:
go :: forall a1. Int -> [a1] -> Int
• In the expression: ((take n xs) == (take (n + 1) xs))
In a stmt of a pattern guard for
an equation for ‘go’:
((take n xs) == (take (n + 1) xs))
In an equation for ‘go’:
go n xs
| ((take n xs) == (take (n + 1) xs)) = n
| otherwise = go (n + 1) xs
|
10 | | ( (take n xs) == (take (n+1) xs) ) = n
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
As far as I understood, the reason for the error it that when we try to compare the lists returned from (take n xs) and (take (n+1) xs), the compiler does not know the types of lists in advance, so it cannot compare them, and this is why it complains, so before this line, I need to tell the compiler that both return values are the same type, and the type is [a], but how can we do that ?
A confusion: when we specify the type signature of go, we are explicitly fixing the what is the type of xs, i.e so shouldn't the list that is return by the function take have the same type, namely [a], hence shouldn't the compiler be able to compare them ?
Edit:
Note that, I have another function in the definition of a function, and there are lots of things that are different from the question that is marked as duplicate, and as you can observe, the given answer to that question does not fully solves this question.
What you need is instance contexts (here Eq a), which is indicated by =>:
myLength :: Eq a => [a] -> Int
myLength [] = 0
myLength ys = go 1 ys
where
go :: Eq a => Int -> [a] -> Int
go n xs
| ( (take n xs) == (take (n+1) xs) ) = n
| otherwise = go (n+1) xs
But this is not a proper answer to the question #4, because it adds an additional constraint to the function.
EDIT: For the question "Shouldn't every list be equality comparable?":
Lists are comparable iff their elements are comparable. For example, functions, Kleisli arrows, WrappedArrows are not equality comparable, so aren't lists of them.
{-# Language ScopedTypeVariables #-}
myLength :: forall a. Eq a => [a] -> Int
myLength [] = 0
myLength ys = go 1 ys
where
go :: Int -> [a] -> Int
go n xs
| take n xs == take (n+1) xs = n
| otherwise = go (n+1) xs

Double every other element of list from right in Haskell

I have a list and I want to double every other element in this list from the right.
There is another related question that solves this problem but it doubles from the left, not the right: Haskell: Double every 2nd element in list
For example, in my scenario, [1,2,3,4] would become [2,2,6,4], and in that question, [1,2,3,4] would become [1,4,3,8].
How would I implement this?
I think that the top answer misinterpreted the question. The title clearly states that the OP wants to double the second, fourth, etc. elements from the right of the list. Ørjan Johansen's answer is correct, but slow. Here is my more efficient solution:
doubleFromRight :: [Integer] -> [Integer]
doubleFromRight xs = fst $ foldr (\x (acc, bool) ->
((if bool then 2 * x else x) : acc,
not bool)) ([], False) xs
It folds over the list from the right. The initial value is a tuple containing the empty list and a boolean. The boolean starts as false and flips every time. The value is multiplied by 2 only if the boolean is true.
OK, as #TomEllis mentions, everyone else seems to have interpreted your question as about odd-numbered elements from the left, instead of as even-numbered from the right, as your title implies.
Since you start checking positions from the right, there is no way to know what to double until the end of the list has been found. So the solution cannot be lazy, and will need to temporarily store the entire list somewhere (even if just on the execution stack) before returning anything.
Given this, the simplest solution might be to just apply reverse before and after the from-left solution:
doubleFromRight = reverse . doubleFromLeft . reverse
Think about it.
double = zipWith ($) (cycle [(*2),id])
EDIT I should note, this isn't really my solution it is the solution of the linked post with the (*2) and id flipped. That's why I said think about it because it was such a trivial fix.
A direct implementation would be:
doubleOddElements :: [Int] -> [Int]
doubleOddElements [] = []
doubleOddElements [x] = [2 * x]
doubleOddElements (x:y:xs) = (2*x):y:(doubleOddElements xs)
Okay, so not elegant or efficient like the other answers, but I wrote this from a beginners standpoint (I am one) in terms of readability and basic functionality.
This doubles every second number, beginning from the right.
Using this script: doubleEveryOther [1,3,6,9,12,15,18] produces [1,6,6,18,12,30,18] and doubleEveryOther [1,3,6,9,12,15] produces [2,3,12,9,24,15]
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther [] = []
doubleEveryOther (x:[]) = [x]
doubleEveryOther (x:y:zs)
| (length (x:y:zs)) `mod` 2 /= 0 = x : y*2 : doubleEveryOther zs
| otherwise = x*2 : y : doubleEveryOther zs
Trying to generalize the problem a bit: Since we want to double every 2nd element from the end, we can't know in advance if it'll be every odd or even from the start. So the easiest way is to construct both, count if the overall size is even or odd, and then decide.
Let's define an Applicative data structure that captures:
Having two variants of values,
keeping the parity of the length (odd/even), and
alternating the two when two such values are combined,
as follows:
import Control.Applicative
import Data.Monoid
import qualified Data.Traversable as T
data Switching m = Switching !Bool m m
deriving (Eq, Ord, Show)
instance Functor Switching where
fmap f (Switching b x y) = Switching b (f x) (f y)
instance Applicative Switching where
pure x = Switching False x x
(Switching False f g) <*> (Switching b2 x y) = Switching b2 (f x) (g y)
(Switching True f g) <*> (Switching b2 x y) = Switching (not b2) (f y) (g x)
So traversing a list will yield two lists looking like this:
x1 y2 x3 y4 ...
y1 x2 y3 x4 ...
two zig-zag-ing copies. Now we can compute
double2 :: (Num m) => m -> Switching m
double2 x = Switching True (2 * x) x
double2ndRight :: (Num m, T.Traversable f) => f m -> f m
double2ndRight k = case T.traverse double2 k of
Switching True _ y -> y
Switching False x _ -> x
Here are mine two solutions, note that I'm complete beginner in Haskell.
First one uses list functions, head, tail and lenght:
doubleSecondFromEnd :: [Integer] -> [Integer]
doubleSecondFromEnd [] = [] -- Do nothing on empty list
doubleSecondFromEnd n
| length n `mod` 2 == 0 = head n * 2 : doubleSecondFromEnd (tail n)
| otherwise = head n : doubleSecondFromEnd (tail n)
Second one, similar but with a different approach only uses length function:
doubleSecondFromEnd2 :: [Integer] -> [Integer]
doubleSecondFromEnd2 [] = [] -- Do nothing on empty list
doubleSecondFromEnd2 (x:y)
| length y `mod` 2 /= 0 = x * 2 : doubleSecondFromEnd2 y
| otherwise = x : doubleSecondFromEnd2 y
I am just learning Haskell so please find the following beginner solution. I try to use limited cool functions like zipWith , cycle, or reverse
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther [] = []
doubleEveryOther s#(x:xs)
| (length s) `mod` 2 == 0 = (x * 2) : (doubleEveryOther xs)
| otherwise = x : (doubleEveryOther xs)
The key thing to note that when doubling every element from the right you can put the doubling into two cases:
If the list is even length, you will ultimately end up doubling the first element of the list.
If the list is odd length, you will not be doubling the first element of the list.
I answered this as part of the homework assignment from CS194
My first thought was:
doubleOdd (x:xs) = (2*x):(doubleEven xs)
doubleOdd [] = []
doubleEven (x:xs) = x:(doubleOdd xs)
doubleEven [] = []
DiegoNolan's solution is more elegant, in that the function and sequence length are more easily altered, but it took me a moment to grok.
Adding the requirement to operate from the right makes it a little more complex. foldr is a neat starting point for doing something from the right, so let me try:
doubleOddFromRight = third . foldr builder (id,double,[])
where third (_,_,x) = x
builder x (fx,fy,xs) = (fy, fx, fx x : xs)
double x = 2 * x
This swaps the two functions fx and fy for each entry. To find the value of any entry will require a traversal to the end of the list, finding whether the length was odd or even.
This is my answer to this CIS 194 homework assignment. It's implemented using just the stuff that was introduced in lecture 1 + reverse.
doubleEveryOtherLeftToRight :: [Integer] -> [Integer]
doubleEveryOtherLeftToRight [] = []
doubleEveryOtherLeftToRight (x:[]) = [x]
doubleEveryOtherLeftToRight (x:y:zs) = x:y*2:(doubleEveryOtherLeftToRight zs)
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther xs = reverse (doubleEveryOtherLeftToRight (reverse xs))
How about this for simplicity?
doubleEveryOtherRev :: [Integer] -> [Integer]
doubleEveryOtherRev l = doubleRev (reverse l) []
where
doubleRev [] a = a
doubleRev (x:[]) a = (x:a)
doubleRev (x:y:zs) a = doubleRev zs (2*y:x:a)
You would have to feed a reversed list of digits, in case you followed that course's recommendation, because it will double every other element as it reverses again. I think that this is different than using twice the reverse function, with another to double every other digit in between, because you won't need to know the full extent of their list by the second time. In other words, it solves that course's problem, but someone correct me if I'm wrong.
We can also do it like this:
doubleEveryOther = reverse . zipWith (*) value . reverse
where
value = 1 : 2 : value
Some answers seems not deal with odd/even length of list.
doubleEveryOtherEvenList = zipWith ($) (cycle [(*2),id])
doubleEveryOther :: [Int] -> [Int]
doubleEveryOther n
| length n `mod` 2 == 0 = doubleEveryOtherEvenList n
| otherwise = (head n) : doubleEveryOtherEvenList (tail n)
Taking an edx course in haskell, this is my noob solution.
doubleSecondR :: [Integer] -> [Integer]
doubleSecondR xs = reverse(zipWith (*) (reverse xs) ys)
where ys = repeat' [1,2]
repeat' :: [a] -> [a]
repeat' xs = xs ++ repeat' xs
I'm too coming to this question from the CIS 194 course.
I did this two ways. First I figured that the point of the question should only rely on functions or ways of programming mentioned in either of the 3 possible sources listed. The course lecture 1, Real World Haskell ch. 1,2 and Learn You a Haskell ch. 2.
So OK:
Recursion, conditionals
reverse, basic functions like max, min, odd, even
list functions e.g. head, tail, ...
Not OK:
foldr, foldl, map
Higher Order functions
Anything beyond these
First solution, just using recursion with a counter:
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther xs = loopDoubles xs 1
loopDoubles :: [Integer] -> Integer -> [Integer]
loopDoubles [] _ = []
loopDoubles xs n = loopDoubles (init xs) (n + 1) ++ [doubleEven (last xs) n]
doubleEven :: Integer -> Integer -> Integer
doubleEven x n = if even n then x * 2 else x
This method uses recursion, but avoids calculating the length at each level of the recursion.
Second method breaking the aforemention rules of mine:
doubleEveryOther' :: [Integer] -> [Integer]
doubleEveryOther' xs = map (\x -> if even (fst x) then (snd x) * 2 else snd x) $ zip (reverse [1..n]) xs
where n = length(xs)
This second one works by building up a reversed set of indexes and then mapping over these. This does calculate the length but only once.
e.g. [1,1,1,1] -> [(4,1),(3,1),(2,1),(1,1)]
Both of these are following the requirement of doubling every other element from the right.
> doubleEveryOther [1,2,3,4]
[2,2,6,4]
> doubleEveryOther [1,2,3]
[1,4,3]
> doubleEveryOther' [1,2,3,4]
[2,2,6,4]
> doubleEveryOther' [1,2,3]
[1,4,3]
I'm guessing the OP posed this question while researching an answer to the Homework 1 assignment from Haskell CIS194 Course. Very little Haskell has been imparted to the student at that stage of the course, so while the above answers are correct, they're beyond the comprehension of the learning student because elements such as lambdas, function composition (.), and even library routines like length and reverse haven't been introduced yet. Here is an answer that matches the stage of teaching in the course:
doubleEveryOtherEven :: [Integer] -> [Integer]
doubleEveryOtherEven [] = []
doubleEveryOtherEven (x:y:xs) = x*2 : y : doubleEveryOtherEven xs
doubleEveryOtherOdd :: [Integer] -> [Integer]
doubleEveryOtherOdd (x:[]) = [x]
doubleEveryOtherOdd (x:y:xs) = x : y*2 : doubleEveryOtherOdd xs
integerListLen :: [Integer] -> Integer
integerListLen [] = 0
integerListLen (x:xs) = 1 + integerListLen xs
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther xs
| integerListLen xs `mod` 2 == 0 = doubleEveryOtherEven xs -- also handles empty list case
| otherwise = doubleEveryOtherOdd xs
The calculation requires foreknowledge on whether the list has an even or odd number of elements, to determine which digit in each pair of digits should be doubled. However, basic Haskell pattern-matching only permits matching list elements from left-to-right (example: x:xs), which means you can't determine if there are an odd or even number of elements until you've reached the end of the list, but by then it's too late since you need to do calculations on each left-hand pair of elements while working through the list to reach the end.
The solution is to split the doubling logic into two functions - one which handles even-length lists and another which handles odd-length lists. A third function is needed to determine which of those two functions to call for a given list, which in turn needs an additional function that can calculate the length of the list so we can establish whether the list has an odd or even number of elements (again, since the length library function hasn't been introduced at this stage of the course).
This solution is also in keeping with the advisory in the Week 1 lesson, which states: "It’s good Haskell style to build up more complex functions by combining many simple ones."
Here is my answer for CIS 194 homework1.
I took idea from toDigits and toDigitsRev. It's not fancy, but works.
takeLastTwo :: [Int] -> [Int]
takeLastTwo [] = []
takeLastTwo (x : y : []) = [x, y]
takeLastTwo (x : xs) = takeLastTwo xs
removeLastTwo :: [Int] -> [Int]
removeLastTwo [] = []
removeLastTwo (x : y : []) = []
removeLastTwo (x : xs) = x : removeLastTwo xs
doubleEveryOther :: [Int] -> [Int]
doubleEveryOther [] = []
doubleEveryOther (x : []) = [x]
doubleEveryOther (x : y : []) = (2 * x) : y : []
doubleEveryOther xs = doubleEveryOther (removeLastTwo xs) ++ doubleEveryOther (takeLastTwo xs)

Haskell List of tuples to list?

Is it possible to convert a list of tuples [(Int,Int)] as a generic way which valid to any input size ? .. i saw in various questions thats its not possible generically
example :
type X = [(Int,Int)]
func :: X -> [Int]
Your question is not very certain about how the tuples should be converted into a list. I assume that you want to have them flattend - for instance, [(1,2),(3,4)] should become [1,2,3,4].
This translation is only possible, if the two elements of your tuple are of the same type. In this case you can do something like this:
tupleToList :: [(a,a)] -> [a]
tupleToList ((a,b):xs) = a : b : tupleToList xs
tupleToList _ = []
In the general case, such a translation is impossible. One thing I could imagine to make the impossible possible is to use Either to wrap up the two different types:
tupleToList :: [(a,b)] -> [Either a b]
tupleToList ((a,b):xs) = Left a : Right b : tupleToList xs
The lens library handles this and similar cases consistently.
> import Control.Lens
> toListOf (traverse . both) [(1,2),(3,4)]
^ ^
| |> Traversal of the tuple (a, a)
|> Traversal of a list [b]
[1,2,3,4]
To convert from a list of lists:
> toListOf (traverse . traverse) [[1,2],[3,4],[5,6,7]]
[1,2,3,4,5,6,7]
addition edit:
traverse works with Traversable
traverse will work with any datatype that has a Traversable instance, for example trees.
> import Data.Tree
> let t = Node 1 [Node 2 [Node 3 [], Node 4 []], Node 5 []]
> let prettyTree = drawTree . fmap show
> prettyTree t
1
|
+- 2
| |
| +- 3
| |
| `- 4
|
`- 5
> toListOf (traverse . traverse) [t, t]
[1,2,3,4,5,1,2,3,4,5]
You could also use a fold and avoid explicit recursion:
tupleToList = foldr (\(f,s) a -> f : s : a) []
Or:
tupleToList = foldl (\a (f,s) -> a ++ [f,s]) []
(For elements of the same type)
This can be also achieved by the homogeneous tuples library (disclaimer: which I'm the author of). It defines wrappers for tuples that make them instances of Traversable (and others such as Applicative and Monad). So a tuple can be converted to a list by toList . Tuple2 (where toList is from Data.Foldable) and
f :: [(a, a)] -> [a]
f = concatMap (toList . Tuple2)
You can also use it for other tuples, for example concatMap (toList . Tuple5) etc.
f [] = []
f [(x, y) : xs] = x : y : f xs

Recursively sort non-contiguous list to list of contiguous lists

I've been trying to learn a bit of functional programming (with Haskell & Erlang) lately and I'm always amazed at the succinct solutions people can come up with when they can think recursively and know the tools.
I want a function to convert a list of sorted, unique, non-contiguous integers into a list of contiguous lists, i.e:
[1,2,3,6,7,8,10,11]
to:
[[1,2,3], [6,7,8], [10,11]
This was the best I could come up with in Haskell (two functions)::
make_ranges :: [[Int]] -> [Int] -> [[Int]]
make_ranges ranges [] = ranges
make_ranges [] (x:xs)
| null xs = [[x]]
| otherwise = make_ranges [[x]] xs
make_ranges ranges (x:xs)
| (last (last ranges)) + 1 == x =
make_ranges ((init ranges) ++ [(last ranges ++ [x])]) xs
| otherwise = make_ranges (ranges ++ [[x]]) xs
rangify :: [Int] -> [[Int]]
rangify lst = make_ranges [] lst
It might be a bit subjective but I'd be interested to see a better, more elegant, solution to this in either Erlang or Haskell (other functional languages too but I might not understand it.) Otherwise, points for just fixing my crappy beginner's Haskell style!
Most straightforward way in my mind is a foldr:
ranges = foldr step []
where step x [] = [[x]]
step x acc#((y:ys):zs) | y == x + 1 = (x:y:ys):zs
| otherwise = [x]:acc
Or, more concisely:
ranges = foldr step []
where step x ((y:ys):zs) | y == x + 1 = (x:y:ys):zs
step x acc = [x]:acc
But wait, there's more!
abstractRanges f = foldr step []
where step x ((y:ys):zs) | f x y = (x:y:ys):zs
step x acc = [x]:acc
ranges = abstractRanges (\x y -> y == x + 1)
powerRanges = abstractRanges (\x y -> y == x*x) -- mighty morphin
By turning the guard function into a parameter, you can group more interesting things than just +1 sequences.
*Main> powerRanges [1,1,1,2,4,16,3,9,81,5,25]
[[1,1,1],[2,4,16],[3,9,81],[5,25]]
The utility of this particular function is questionable...but fun!
I can't believe I got the shortest solution. I know this is no code golf, but I think it is still quite readable:
import GHC.Exts
range xs = map (map fst) $ groupWith snd $ zipWith (\a b -> (a, a-b)) xs [0..]
or pointfree
range = map (map snd) . groupWith fst . zipWith (\a b -> (b-a, b)) [0..]
BTW, groupWith snd can be replaced with groupBy (\a b -> snd a == snd b) if you prefer Data.List over GHC.Exts
[Edit]
BTW: Is there a nicer way to get rid of the lambda (\a b -> (b-a, b)) than (curry $ (,) <$> ((-) <$> snd <*> fst) <*> snd) ?
[Edit 2]
Yeah, I forgot (,) is a functor. So here is the obfuscated version:
range = map (map fst) . groupWith snd . (flip $ zipWith $ curry $ fmap <$> (-).fst <*> id) [0..]
Suggestions are welcome...
import Data.List (groupBy)
ranges xs = (map.map) snd
. groupBy (const fst)
. zip (True : zipWith ((==) . succ) xs (tail xs))
$ xs
As to how to come up with such a thing: I started with the zipWith f xs (tail xs), which is a common idiom when you want to do something on consecutive elements of a list. Likewise is zipping up a list with information about the list, and then acting (groupBy) upon it. The rest is plumbing.
Then, of course, you can feed it through #pl and get:
import Data.List (groupBy)
import Control.Monad (ap)
import Control.Monad.Instances()
ranges = (((map.map) snd)
. groupBy (const fst))
.) =<< zip
. (True:)
. ((zipWith ((==) . succ)) `ap` tail)
, which, by my authoritative definition, is evil due to Mondad ((->) a). Twice, even. The data flow is meandering too much to lay it out in any sensible way. zipaptail is an Aztec god, and Aztec gods aren't to be messed with.
Another version in Erlang:
part(List) -> part(List,[]).
part([H1,H2|T],Acc) when H1 =:= H2 - 1 ->
part([H2|T],[H1|Acc]);
part([H1|T],Acc) ->
[lists:reverse([H1|Acc]) | part(T,[])];
part([],Acc) -> Acc.
k z = map (fst <$>) . groupBy (const snd) .
zip z . (False:) . (zipWith ((==) . succ) <*> tail) $ z
Try reusing standard functions.
import Data.List (groupBy)
rangeify :: (Num a) => [a] -> [[a]]
rangeify l = map (map fst) $ groupBy (const snd) $ zip l contigPoints
where contigPoints = False : zipWith (==) (map (+1) l) (drop 1 l)
Or, following (mixed) advice to use unfoldr, stop abusing groupBy, and be happy using partial functions when it doesn't matter:
import Control.Arrow ((***))
import Data.List (unfoldr)
spanContig :: (Num a) => [a] -> [[a]]
spanContig l =
map fst *** map fst $ span (\(a, b) -> a == b + 1) $ zip l (head l - 1 : l)
rangeify :: (Num a) => [a] -> [[a]]
rangeify = unfoldr $ \l -> if null l then Nothing else Just $ spanContig l
Erlang using foldr:
ranges(List) ->
lists:foldr(fun (X, [[Y | Ys], Acc]) when Y == X + 1 ->
[[X, Y | Ys], Acc];
(X, Acc) ->
[[X] | Acc]
end, [], List).
This is my v0.1 and I can probably make it better:
makeCont :: [Int] -> [[Int]]
makeCont [] = []
makeCont [a] = [[a]]
makeCont (a:b:xs) = if b - a == 1
then (a : head next) : tail next
else [a] : next
where
next :: [[Int]]
next = makeCont (b:xs)
And I will try and make it better. Edits coming I think.
As a comparison, here's an implementation in Erlang:
partition(L) -> [lists:reverse(T) || T <- lists:reverse(partition(L, {[], []}))].
partition([E|L], {R, [EL|_] = T}) when E == EL + 1 -> partition(L, {R, [E|T]});
partition([E|L], {R, []}) -> partition(L, {R, [E]});
partition([E|L], {R, T}) -> partition(L, {[T|R], [E]});
partition([], {R, []}) -> R;
partition([], {R, T}) -> [T|R].
The standard paramorphism recursion scheme isn't in Haskell's Data.List module, though I think it should be. Here's a solution using a paramorphism, because you are building a list-of-lists from a list, the cons-ing is a little tricksy:
contig :: (Eq a, Num a) => [a] -> [[a]]
contig = para phi [] where
phi x ((y:_),(a:acc)) | x + 1 == y = (x:a):acc
phi x (_, acc) = [x]:acc
Paramorphism is general recursion or a fold with lookahead:
para :: (a -> ([a], b) -> b) -> b -> [a] -> b
para phi b [] = b
para phi b (x:xs) = phi x (xs, para phi b xs)
It can be pretty clear and simple in the Erlang:
partition([]) -> [];
partition([A|T]) -> partition(T, [A]).
partition([A|T], [B|_]=R) when A =:= B+1 -> partition(T, [A|R]);
partition(L, P) -> [lists:reverse(P)|partition(L)].
Edit: Just for curiosity I have compared mine and Lukas's version and mine seems about 10% faster either in native either in bytecode version on testing set what I generated by lists:usort([random:uniform(1000000)||_<-lists:seq(1,1000000)]) on R14B01 64b version at mine notebook. (Testing set is 669462 long and has been partitioned to 232451 sublists.)
Edit2: Another test data lists:usort([random:uniform(1000000)||_<-lists:seq(1,10000000)]), length 999963 and 38 partitions makes bigger diference in native code. Mine version finish in less than half of time. Bytecode version is only about 20% faster.
Edit3: Some microoptimizations which provides additional performance but leads to more ugly and less maintainable code:
part4([]) -> [];
part4([A|T]) -> part4(T, A, []).
part4([A|T], B, R) when A =:= B+1 -> part4(T, A, [B|R]);
part4([A|T], B, []) -> [[B]|part4(T, A, [])];
part4([A|T], B, R) -> [lists:reverse(R, [B])|part4(T, A, [])];
part4([], B, R) -> [lists:reverse(R,[B])].
Here's an attempt from a haskell noob
ranges ls = let (a, r) = foldl (\(r, a#(h:t)) e -> if h + 1 == e then (r, e:a) else (a:r, [e])) ([], [head ls]) (tail ls)
in reverse . map reverse $ r : a

Resources