How to handle the last case? - haskell

Define a helper function mergers that given all parts of a word, produces a pair of all possible ways to break up the word.  This recursively. The concat function might help you.   
I can seem to use map and concat to solve this problem. I've solved the first 3 cases which were much easier but cant solve the last one.
mergers :: [String] ->[(String,String)]
mergers [] = []
mergers (x:xs)
| xs ==[] = []
mergers (x:xs:xy)
| xy ==[] = [(x,xs)]
mergers (x:xs:xy:_) ->
The function:
mergers ["co","nt","ro","ls"]
should produce all the possible combination of the given strings like
[("co","ntrols"),("cont","rols"),("contro","ls")] 
 
mergers ["co","nt"]
should give
[("co","nt")]  
mergers ["co"]
should return an empty list
[]

The given function will not suffice. Especially since you need to keep track of the items that have passed. We thus probably should use a helper function that keeps track of the items obtained thus far. These items are then put in a concatenated form in the first tuple.
We thus can work with a helper function, like:
mergers :: [[a]] -> [([a], [a])]
mergers [] = []
mergers (x:xs) = helper [x] xs
where helper left right = …
Now in the helper function, if the right list is empty, than we can stop to produce a list. If on the other hand the right list is not-empty, we can emit a 2-tuple where we concatenate both the left and the right in the tuple, and add the first item of the right list to the left if we recurse.
EDIT: since you managed to solve it, we can here yield the items with:
mergers :: [[a]] -> [([a], [a])]
mergers [] = []
mergers (x:xs) = helper [x] xs
where helper _ [] = []
helper la ra#(r:rs) = (concat la, concat ra) : helper (la ++ [r]) rs
This then yields the expected output:
Prelude> mergers ["co","nt","ro","ls"]
[("co","ntrols"),("cont","rols"),("contro","ls")]
Prelude> mergers ["co","nt"]
[("co","nt")]
Prelude> mergers ["co"]
[]

Related

Haskell: merging list of lists

given a list of list pairs ::[a,a], I would like to return the possible combinations of lists, where the sublists have been merged on the last of one sublit matching head of the next.
for example
-- combine two lists if they front and back match
merge :: Eq a => [[a]] -> [[a]]
merge (x:y:ys) | last x == head y = merge $ (x ++ (drop 1 y)) : ys
| otherwise = []
merge xs = xs
combinations :: Eq a => [[a]] -> [[a]]
combinations = nub . concatMap merge . permutations
λ= merge [1,2] [2,3]
[1,2,3]
-- there should be no duplicate results
λ= combinations [[1,3],[1,3],[1,3],[1,3],[2,1],[2,1],[2,1],[2,2],[3,2],[3,2],[3,2]]
[[1,3,2,2,1,3,2,1,3,2,1,3],[1,3,2,1,3,2,2,1,3,2,1,3],1,3,2,1,3,2,1,3,2,2,1,3]]
-- the result must be a completely merged list or an empty list
λ= combinations [[1,3], [3,1], [2,2]]
[]
λ= combinations [[1,3], [3, 1]]
[[1,3,1],[3,1,3]]
λ= combinations [[1,3],[3,1],[3,1]]
[[3,1,3,1]]
I can't quite wrap my head around the recursion needed to do this efficiently.
I ended with this solution, but it contains duplicates (you can use Data.List(nub) to get rid of them).
import Data.List(partition)
main :: IO ()
main = do
print $ show tmp
input = [[1,3],[1,3],[1,3],[1,3],[2,1],[2,1],[2,1],[2,2],[3,2],[3,2],[3,2]]
tmp = combinations input
-- this function turns list into list of pair, first element is element of the
-- input list, second element is rest of the list
each :: [a] -> [a] -> [(a, [a])]
each h [] = []
each h (x:xs) = (x, h++xs) : each (x:h) xs
combinations :: (Eq a) => [[a]] -> [[a]]
combinations l = concat $ map combine $ each [] l
where
-- take pair ("prefix list", "unused lists")
combine :: (Eq a) => ([a], [[a]]) -> [[a]]
combine (x, []) = [x]
combine (x, xs) = let
l = last x
-- split unused element to good and bad
(g, b) = partition (\e -> l == head e) xs
s = each [] g
-- add on element to prefix and pass rest (bad + good except used element) to recursion. so it eat one element in each recursive call.
combine' (y, ys) = combine (x ++ tail y, ys ++ b)
-- try to append each good element, concat result
in concat $ map combine' s
I'm not sure if I fully understand what you want to do, so here are just a few notes and hints.
given a list of list pairs ::[a,a]
(...) for example
λ= merge [1,2] [2,3]
Firstly those are not lists of pairs, each element of the list is an integer not a pair. They just happen to be lists with two elements. So you can say they are of type [Int] or an instance of type [a].
the sublists have been merged on the last of one sublit matching head of the next.
This suggests that the size of the lists will grow, and that you will constantly need to inspect their first and last elements. Inspecting the last element of a list implies traversing it each time. You want to avoid that.
This suggests a representation of lists with extra information for easy access. You only need the last element, but I'll put first and last for symmetry.
-- lists together with their last element
data CL a = CL [a] a a
cl :: [a] -> CL a
cl [] = error "CL from empty list"
cl xs = CL xs (head xs) (last xs)
clSafe :: [a] -> Maybe (CL a)
clSafe [] = Nothing
clSafe xs = Just (cl xs)
clFirst (CL _ x _) = x
clLast (CL _ _ x) = x
compatible cs ds = clLast cs == clFirst ds
Perhaps better, maybe you should have
data CL a = CL [a] a a | Nil
And to include an empty list that is compatible with all others.
Another point to take into account is that if e.g., you have a list xs and want to find lists ys to combine as ys++xs, then you want it to be very easy to access all ys with a given last element. That suggests you should store them in a suitable structure. Maybe a hash table.

How to write a a reverse function in Haskell

So, I know, there is a built in function to reverse a list in Haskell, but I'm trying to write my own little function, just to practice some Haskell. I thought of the following code, which sadly is not working. Could you guys tell me what I did wrong?
rev :: [Int] -> [Int]
rev [] = []
rev [x] = last [x] : rev init [x]
If you want to do it efficiently, I'd recommend you use an accumulator:
rev :: [a] -> [a]
rev xs = go xs []
where
go :: [a] -> [a] -> [a]
go [] ys = ys
go (x:xs) ys = go xs (x:ys)
The function go, at each step, removes one element from the first list xs and prepends it to the second list ys. This is similar to popping from a stack and pushing to another stack -- which reverses the order.
Since we only use a constant amount of time at each recursive call, we get O(n) complexity, where n is the list length.
Instead, if at each recursive call we use last or append with ... ++ [x], we pay O(n) for each call, hence O(n^2) overall.
You almost had it.
rev :: [Int] -> [Int]
rev [] = []
rev x = last x : rev (init x)
Explanation: [x] was a list containing x, whereas you want to operate directly with x
ps. here's the documentation for Data.List. And remember to import Data.List
Well, you could do something like this:
rev :: [Int] -> [Int]
rev [] = []
rev (x:l) = (rev l) ++ [x]
The 3rd line takes the first element from the list and then creates a list containing only that element. This is appended to the result of the recursion rev l call.

Gen for a custom data type in Haskell

I was trying to make a truth table for a list of strings.
Say, I have a list ["a","b"] and as an output, I want
[[("a",True),("b",True)],
[("a",True),("b",False)],
[("a",False),("b",True)],
[("a",False),("b",False)]]
Each of those instances in the truth table are a custom data type defined as
data TableRow = [(String,Bool)]
Is there any easier way of doing this? Until now I have been doing this
genRow :: [String] -> [TableRow]
genRow [] = []
genRow (x:xs) = ((makeRow x True) : genRow xs) ++
((makeRow x False) : genRow xs)
Quite obviously, this does not quite give me what I expect. Note that makeRow just takes in a String and a Bool and returns a TableRow.
Is there any cleaner way of doing this? Thanks
The problem with your program is that genRow :: [String] -> [TableRow] generates a list of TableRow elements, and you cannot use the cons (:) constructor on a (String,Bool) and TableRow since TableRow is [[(String,Bool)]].
You can however easily use list comprehension for that:
genRow :: [String] -> [[(String,Bool)]]
genRow [] = [[]]
genRow (x:xs) = [(x,b):ti | b <- [True,False], ti <- ts]
where ts = genRow xs
The first statement should thus generate a list with one element: the empty list [] (not the empty list as result). Furthermore we use list comprehension: we iterate over the two Bools True and False for b and for each such value, we iterate over the possible values as tails ts and prepend the (x,b) to each of the possible tails.
This gives:
*Main> genRow ["A","B","C"]
[[("A",True),("B",True),("C",True)],
[("A",True),("B",True),("C",False)],
[("A",True),("B",False),("C",True)],
[("A",True),("B",False),("C",False)],
[("A",False),("B",True),("C",True)],
[("A",False),("B",True),("C",False)],
[("A",False),("B",False),("C",True)],
[("A",False),("B",False),("C",False)]]
*Main> genRow ["Foo","Bar"]
[[("Foo",True),("Bar",True)],
[("Foo",True),("Bar",False)],
[("Foo",False),("Bar",True)],
[("Foo",False),("Bar",False)]]
(new lines added for readability)

List partitioning implemented recursively

I am a Haskell beginner and I have been experimenting with recursive functions.
I am working on a function:
separate :: [a] -> [[[a]]]
that takes in a list and outputs all of the partitions of that list.
For example 123 becomes:
1|2|3
12|3
1|23
13|2
132
I have only been able to implement a recursive function that creates the 1|2|3 variant:
separate' :: [a] -> [[a]]
separate' (r:rs) = [r]:separate' xs
>separate [1,2,3]
[[1],[2],[3]]
I am stuck with trying to create the other variants with recursion.
You can think of this function as choosing, for each place in between two list elements, whether to include a split there. So for starters, there should be 2n-1 partitions for an n-element list: you can use that as a quick sanity check on a possible solution.
One good way to model non-determinism is with the list monad (or equivalently with list comprehensions), so let's do it that way.
First, let's write the type and a base case:
separate :: [a] -> [[[a]]]
separate [] = [[]]
There is a single way to separate an empty list: the empty list itself, with no possibility of splits. Easy enough.
Now, given we have one element and a list of remaining elements, one thing we'll need for sure is a list of all the ways to split the remaining elements:
separate :: [a] -> [[[a]]]
separate [] = [[]]
separate (x:xs) = let recur = separate xs
in undefined -- TODO
Here's where the interesting stuff starts. As I said, you can view this as choosing, for each item, whether to put a split after it. Two choices means concatenating together two lists, so let's do that:
separate :: [a] -> [[[a]]]
separate [] = [[]]
separate (x:xs) = let recur = separate xs
split = undefined -- TODO
noSplit = undefined -- TODO
in split ++ noSplit
Now, how do we introduce a split after the item x? We do it by, for each partition in recur, adding [x] to the front of it as a new partition:
separate :: [a] -> [[[a]]]
separate [] = [[]]
separate (x:xs) = let recur = separate xs
split = do
partition <- recur
return $ [x] : partition
noSplit = undefined -- TODO
in split ++ noSplit
What about not splitting? Pretty similar! For each partition in recur, we add x to the front of the first sub-partition:
separate :: [a] -> [[[a]]]
separate [] = [[]]
separate (x:xs) = let recur = separate xs
split = do
partition <- recur
return $ [x] : partition
noSplit = do
(y:ys) <- recur
return $ (x:y):ys
in split ++ noSplit
And with that, we're done:
*Temp> separate "123"
[["1","2","3"],["1","23"],["12","3"],["123"]]
A right fold solution would be:
import Control.Applicative ((<$>))
separate :: Foldable t => t a -> [[[a]]]
separate = foldr (\i -> concatMap (inc i)) [[]]
where
inc i [] = [[[i]]]
inc i (x:xs) = ((i:x):xs):((x:) <$> inc i xs)
then:
\> separate [1, 2]
[[[1,2]],[[2],[1]]]
\> separate [1, 2, 3]
[[[1,2,3]],[[2,3],[1]],[[1,3],[2]],[[3],[1,2]],[[3],[2],[1]]]

Numeration count inside a recursive function

I want do do something like:
>enumerate ["banana", "potato", "ice"]
[(1, "banana"), (2, "potato"), (3, "ice")]
I wrote:
enumerate :: [String] -> [(Int, String)]
enumerate [] = []
How may I control/manage the int counter ? Is there a way to do that without a support function ?
Update: I know about Zip function. But for matter of study, I want to implement my own zip function.
Update 2: Currently Code
This is what I did so far, using a support function. Considering that:
1) I want to implement my own zip function;
2) I do not want to change the function struct:
enumerate :: [String] -> [(Int, String)]
enumerate :: [String]->[(Int,String)]
enumerate [] = []
enumerate list = aux 1 list
aux :: Int->[String]->[(Int, String)]
aux _ [] = []
aux i (x:xs) = [(i, x)] ++ aux (i+1) xs
Is it possible to improve this function ? As I don't want to add one more last to the function, so I think support function is the only way to go, right ?
Don't be afraid to write a support function, in fact, see it as opportunity: Why the arbitrary starting value 1? Why not have a function
>enumerateFrom 42 ["banana", "potato", "ice"]
[(42, "banana"), (43, "potato"), (44, "ice")]
Once you have that, enumerate is easy.
Edit:
Either give your aux function a real name, IMHO enumerateFrom is good or move it into a where clause if you know that already. And listen to chi, use x : ... instead of [x] ++ ...
There is already a function which does this called zip (zip :: [a] -> [b] -> [(a,b)]). Now for your function you just can pass a list with 1,2,... as first argument and get your result, e.g.
enumerate :: [String] -> [(Int, String)]
enumerate = zip [1..]
EDIT:
If you also want to implement your own zip function, just use:
zip' :: [a] -> [b] -> [(a,b)]
zip' _ [] = []
zip' [] _ = []
zip' (x:xs) (y:ys) = (x,y):zip' xs ys
You take two lists ([a] and [b]) and put each element into a tuple. Edge cases are of cores when one of the lists is empty you return an empty list. Otherwise you use pattern matching to get the first element of the list put them into a tuple and call zip' again with the tail of the list.
As you clarified you wanted to implement your own zip:
zip' [] _ = []
zip' _ [] = []
zip' (x:xs) (y:ys) = (x,y) : zip' xs ys

Resources