Combining two nested lists as one nested list - haskell

I want to combine two lists of lists and get a new nested list,Here is my code:
getAllPaths ::(Eq a) => [(a,a)] -> [[a]]
getAllPaths [] = [[]]
getAllPaths (x:xs) = findAllPath (fst x) xs ++ getAllPaths xs
I want to combine the nested list returned from the findAllPath with all the elements from the recursive calls which are also nested list.
I know that ++ is used for combining two lists and no nested list but i also can't use first concat and then ++ because then list will be flatten.
Here is the type signature of findAllPath and function also:
findAllPath ::(Eq a) => a -> [(a,a)] -> [[a]]
findAllPath val list = path val list
where
(first,second) = partition((==val).fst) list
singl = map snd first
path val list
| first == [] = [[val]]
| otherwise = map ((:) val) $ concat $ map (\x -> findAllPath x list) singl
This functionr returns all the possible paths from one node. I want to collect all the possible paths from all nodes.
For example, there are few paths from node 1 and 2 like this:
from node 1 to [[1,2,3],[1,4,6]]
from node 2 to [[2,7,9],[2,0,6]]]
and i want a combination of [[1,2,3],[1,4,6],[2,7,9],[2,0,6]]
Can someone tell me how do it combine them in recursive call?

As WillemVanOnsem mentions in the comments, you're looking for (++). It may not be immediately obvious from the type signature but consider:
(++) :: [a] -> [a] -> [a]
-- if a ~ [b] then the specific type is:
(++) :: [[b]] -> [[b]] -> [[b]]
And by experiment:
GHCi, version 8.2.1: http://www.haskell.org/ghc/ :? for help
Prelude> [[1,2,3],[1,4,6]] ++ [[2,7,9],[2,0,6]]
[[1,2,3],[1,4,6],[2,7,9],[2,0,6]]
If you have a whole list of these, you can combine with foldr.
foldr (++) [] (results :: [[[a]]])
or indeed concat
concat (results :: [[[a]]])

Related

Generating a set using higher order functions and unions

I am studying a past exam and I came across a question where I must write a function called setFunc to generate a set where I apply a function on each element in a list of tuples (which are a result of the Cartesian product operation)
First I implemented a helper function to take the union of sets:
Then I tried to implement the main function:
setFunc x y = f x y
setFunc (x:xs) (y:ys) = (f x y) OrdUnion (setFunc f xt ys)
Help on fixing setFunc would be appreciated.
I must use ordUnion somehow and I am not permitted to use sort.
This sort of constraint is expected to appear within the body of the question.
A core part of the problem is that we want the output list to be sorted (from your example), but we are told nothing about possible order-preserving properties of the argument function. So we must accept that the f x y output values will be produced in some unpredictable random order.
For example, we expect this equality to hold:
setFunc (*) [-7,2] [-7,3] == [-21,-14,6,49]
that is, the maximal output value results from the two minimal input values.
Hence, we are somewhat coerced into solving the problem in 2 steps:
produce the f x y output values in whatever order
sort the list produced in step 1.
Let's call the step 1 function cartesianFunc. It is easy to write it in recursive fashion:
cartesianFunc :: Ord c => (a -> b -> c) -> [a] -> [b] -> [c]
cartesianFunc f [] ys = []
cartesianFunc f (x:xs) ys = (map (f x) ys) ++ (cartesianFunc f xs ys)
Note that we have dropped the useless Ord constraints on types b and c.
Testing:
$ ghci
GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help
...
λ>
λ> :load q13784671.hs
[1 of 1] Compiling Main ( q13784671.hs, interpreted )
Ok, one module loaded.
λ>
λ> cartesianFunc (*) [1,2,4] [1,3,9]
[1,3,9,2,6,18,4,12,36]
λ>
Now for step 2:
We may not use the library sort function. But we have to use function ordUnion, which merges two ordered lists into a bigger ordered list.
Assuming we had yet another function, say splitHalf, which could split a list into two roughly equal parts, we could obtain our own sort function by:
splitting the input list
recursively sorting its two halves
combining our two sorted halves using the merging ordUnion function.
To split a list, we can use the well-know tortoise-hare algorithm where at each iteration, the first part advances by one step and the second part advances by two steps.
This gives this code:
ordUnion :: (Ord a) => [a] -> [a] -> [a]
ordUnion a [] = a
ordUnion [] b = b
ordUnion (x:xs) (y:ys) = case compare x y of
LT -> x : ordUnion xs (y:ys)
EQ -> x : ordUnion xs ys
GT -> y : ordUnion (x:xs) ys
splitHalfTH :: [a] -> ([a],[a])
splitHalfTH xs = th xs xs
where
th (y:ys) (_:_:zs) = let (as,bs) = th ys zs in (y:as, bs)
th ys _ = ([],ys)
mySort :: (Ord a) => [a] -> [a]
mySort [] = []
mySort [a] = [a]
mySort xs = let (as,bs) = splitHalfTH xs in ordUnion (mySort as) (mySort bs)
and finally we can come up with our setFunc function by combining mySort and cartesianFunc:
setFunc :: Ord c => (a -> b -> c) -> [a] -> [b] -> [c]
setFunc fn xs ys = mySort (cartesianFunc fn xs ys)
Testing:
λ>
λ> cartesianFunc (*) [1,2,4] [1,3,9]
[1,3,9,2,6,18,4,12,36]
λ>
λ> mySort $ cartesianFunc (*) [1,2,4] [1,3,9]
[1,2,3,4,6,9,12,18,36]
λ>
λ> setFunc (*) [1,2,4] [1,3,9]
[1,2,3,4,6,9,12,18,36]
λ>

Haskell function that goes through each pair in list and returns a list with size smaller than original by 1

Suppose we have list [1,2,3,4].
I want to take every pair of consecutive elements (i.e. (1,2),(2,3),(3,4)), apply them to some function, and return list which consist of results of this function.
I don't quite understand, how to do this on haskell, since we don't actually have loops and arrays here.
Here are some ways you could try to solve this. The first step will be to get the pairs and the second will be applying the function to the pairs. One way to do the first step is with a recursive function. Now in Haskell lists are made using [] and :, with [1,2,3] being syntactic sugar for 1:(2:(3:[])). So let us write our function:
window [] = []
window [a] = []
window [a,b] = [(a,b)]
window (a:b:r) = (a,b):window (b:r)
Another way we could do this is with the function zip. Recall that this takes two lists, pairs up their elements, and ends the list when either input ends.
window [] = []
window xs = zip xs (tail xs)
The second step is to apply our function to the pairs. We can do this with map (uncurry f). All together:
onWindow f = map (uncurry f) . window
There's several approaches that could work here.
You could use recursion:
mapCons :: (a -> a -> b) -> [a] -> [b]
-- input has at least two elements
mapCons f (a0:a1:as) =
-- use them to compute the head of the output
f a0 a1 :
-- reuse the second element to compute the tail of the output
mapCons f (a1:as)
-- input has less than two elements, so output is the empty list
mapCons _ _ = []
Alternately, zip converts a pair of lists into a list of pairs:
λ zip [1..10] ['a'..'z']
[(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'f'),(7,'g'),(8,'h'),(9,'i'),(10,'j')]
This gives a way to generate all the consecutive pairs in a list by zipping a list with its own tail:
λ zip [1..10] ['a'..'z']
[(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'f'),(7,'g'),(8,'h'),(9,'i'),(10,'j')]
You could then use map to run your function on each pair in the list
λ map (\(a,b) -> 10*a + b) $ zip [0..9] (tail [0..9])
[1,12,23,34,45,56,67,78,89]
This is a common enough pattern that there's a function that combines map and zip: zipWith:
λ :t zipWith
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
λ zipWith (\a b -> 10*a + b) [0..9] (tail [0..9])
[1,12,23,34,45,56,67,78,89]

Apply a function to every element in a list to every element in another list - Haskell

My ultimate goal is to find if a list y contains all the elements of list x (I'm checking if x is a subset of y sort of thing)
subset x y =
and [out | z <- x
, out <- filter (==z) y ]
This doesn't work, and I know it's because z is a list still. I'm trying to make sense of this.
I think I may have to use the elem function, but I'm not sure how to split x into chars that I can compare separately through y.
I'm ashamed to say that I've been working on this simple problem for an hour and a half.
Checking whether all elements of xs are elements of ys is very straightforward. Loop through xs, and for each element, check if it is in ys:
subset xs ys = all (\x -> elem x ys) xs
You could also use the list difference function (\\). If you have list y and list x, and you want to check that all elements of x are in y, then x \\ y will return a new list with the elements of x that are not in y. If all the elements of x are in y, the returned list will be empty.
For example, if your list y is [1,2,3,4,5] and your list x is [2,4], you can do:
Prelude> [2,4] \\ [1,2,3,4,5]
[]
If list y is [1,2,3,4,5] and list x is [2,4,6], then:
Prelude> [2,4,6] \\ [1,2,3,4,5]
[6]
Easy way to reason about subsets is to use sets as the data type.
import qualified Data.Set as S
subset :: Ord a => [a] -> [a] -> Bool
subset xs ys = S.isSubsetOf (S.fromList xs) (S.fromList ys)
Then it's as simple as:
*Main> subset [1..5] [1..10]
True
*Main> subset [0..5] [1..10]
False
Let's break this down into two subproblems:
Find if a value is a member of a list;
Use the solution to #1 to test whether every value in a list is in the second one.
For the first subproblem there is a library function already:
elem :: (Eq a, Foldable t) => a -> t a -> Bool
Lists are a Foldable type, so you can use this function with lists for t and it would have the following type:
elem :: (Eq a) => a -> [a] -> Bool
EXERCISE: Write your own version of elem, specialized to work with lists (don't worry about the Foldable stuff now).
So now, to tackle #2, one first step would be this:
-- For each element of `xs`, test whether it's an element of `ys`.
-- Return a list of the results.
notYetSubset :: Eq a => [a] -> [a] -> [Bool]
notYetSubset xs ys = map (\x -> elem x ys) xs
After that, we need to go from the list of individual boolean results to just one boolean. There's a standard library function that does that as well:
-- Return true if and only if every element of the argument collection is
-- is true.
and :: Foldable t => t Bool -> Bool
EXERCISE: write your own version of and, specialized to lists:
myAnd :: [Bool] -> Bool
myAnd [] = _fillMeIn
myAnd (x:xs) = _fillMeIn
With these tools, now we can write subset:
subset :: Eq a => [a] -> [a] -> [Bool]
subset xs ys = and (map (\x -> elem x ys) xs)
Although a more experienced Haskeller would probably write it like this:
subset :: Eq a => [a] -> [a] -> [Bool]
subset xs ys = every (`elem` ys) xs
{- This:
(`elem` ys)
...is a syntactic shortcut for this:
\x -> x elem ys
-}
...where every is another standard library function that is just a shortcut for the combination of map and and:
-- Apply a boolean test to every element of the list, and
-- return `True` if and only if the test succeeds for all elements.
every :: (a -> Bool) -> [a] -> Bool
every p = and . map p

Haskell from List of Pairs to Pair of Lists

I want to create a simple (involving sets and lists) function that can do the following, and i'm not sure where to start.
split:: [(a,b)] -> ([a],[b])
Let's take it step by step. The two cases for the function are:
split [] = ???
split ((a,b):ps) = ???
One case is easy enough.
split [] = ([], [])
For the other one, we have to use the function recursively, someway
split ((a,b):ps) = ???? where
(as, bs) = split ps
I think it's easy to see that the solution is
split ((a,b):ps) = (a:as, b:bs) where
(as, bs) = split ps
In addition to Guido's solution, there is more than one way to do it in haskell.
Please take a look at fst and snd, which takes the first / second element out of a pair, respectively.
GHCi> :t fst
fst :: (a, b) -> a
GHCi> :t snd
snd :: (a, b) -> b
You should be familiar with map if you are playing with functional programming languages, which takes a function and a list, applies the function on every element of that list, and gives you all the results in another list:
GHCi> :t map
map :: (a -> b) -> [a] -> [b]
Given a list of pairs, you want two lists, one contains all first elements in order, and the other contains all second elements:
GHCi> let split xs = (map fst xs, map snd xs)
GHCi> split [(1,2),(3,4),(5,6)]
([1,3,5],[2,4,6])
GHCi>
One step further, as #jozefg has pointed out in the comment, that this method is not efficient as #Guido 's one, but we can make some changes to improve it (which is exactly what #Guido 's solution):
Now it's time to take a look at how map is implemented here
map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs
so we can try to change our split a little:
we still need the base case, (i.e. what if xs is empty):
split [] = ([], [])
split ls = (map fst ls, map snd ls) -- attention!
and we break the list into head and tail, just like map:
split (x:xs) = (fst x: map fst xs, snd x: map snd xs)
Now we can do a pattern matching, (a,b) = x, so we don't have to call two individual functions to break a pair into two:
split (x:xs) = (a: map fst xs, b: map snd xs)
where (a,b) = x
Compare the code here with the line I commented "attention!", have you realized that if we know the result of (map fst xs, map snd xs), we can simply reuse that result to speed up. Luckily, we already have split ls = (map fst ls, map snd ls)!
Using this fact, we finally come up with this version:
split [] = ([], [])
split (x:xs) = (a:as , b:bs)
where (a,b) = x
(as,bs) = split xs
So there are essentially the same! (but as you can see, the last version we have is more efficient.)

Parse error on pattern

Trying to implement a function that will return a list of ints the represent an ordering of each list of doubles, e.g.:
orderings [ [1.0, 2.0, 3.0], [3.0, 2.0, 1.0] ]
> [ [0, 1, 2], [2, 1, 0] ]
However, having trouble with my pattern matching for some reason:
import Data.List
-- Return a list of orderings for each list of doubles
orderings:: [[Double]] -> [Int]
orderings [] = []
orderings x:xs = (ordering x):(orderings xs)
ordering:: [Double] -> [Int]
ordering xs = [i | (i, _) <- sorted] where
sorted = sortBy (\(i1, e1) (i2,e2) -> compare e1 e2) $ zip [0..] xs
Error is:
Parse error in pattern: orderings
Can't see the error for the life of me!
Two more problems (in addition to the missing parentheses around x:xs):
the type of orderings is wrong; I suspect it should be [[Double]] -> [[Int]]
x is not in scope in ordering; I suspect it should be xs
Here's the corrected code:
import Data.List
-- Return a list of orderings for each list of doubles
orderings:: [[Double]] -> [[Int]] -- changed type
orderings [] = []
orderings (x:xs) = (ordering x):(orderings xs)
ordering:: [Double] -> [Int]
ordering xs = [i | (i, _) <- sorted] where
sorted = sortBy (\(i1, e1) (i2,e2) -> compare e1 e2) $ zip [0..] xs -- xs not x!
The result of orderings should be [[Int]] as pointed out previously. However, the implementation of the functions can be simplified to:
import Data.List
-- Return a list of orderings for each list of doubles
orderings :: [[Double]] -> [[Int]]
orderings = map ordering
ordering :: [Double] -> [Int]
ordering = map snd . sort . flip zip [0..]
You have to put parenthesis around the x:xs pattern:
orderings (x:xs) = ...
There are 3 errors:
In the line orderings x:xs = (ordering x):(orderings xs) you try to cons (:) a list and a list (but cons generates list with the given value prepended) and you forget the parens around the x:xs cons pattern match.
The type of : is:
Prelude> :type (:)
(:) :: a -> [a] -> [a]
The correct form of the line is:
orderings (x:xs) = (ordering x) ++ (orderings xs)
since ++ concats to lists:
Prelude> :type (++)
(++) :: [a] -> [a] -> [a]
The last error is that in the last line, it should be xs instead of x

Resources