Get the first elements of a list of tuples - list

I have this list of tuples
[(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')]
I want to get the first elements of every tuple then replicate it to make the following: "aaaabccaadeeee"
I came up with this code, but it only gives me the replicate of the first tuple.
replicate (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))
--output is: "aaaa"
I was thinking to use map for to get the replicate of every tuple, but I didn't succeed.

Since you already know how to find the correct answer for a single element, all you need is a little recursion
func :: [(Int, a)] -> [a]
func [] = []
func ((n, elem):rest) = (replicate n elem) ++ (func rest)
Mapping the values should also work. You just need to concatenate the resulting strings into one.
func :: [(Int, a)] -> [a]
func xs = concat $ map func2 xs where
func2 (n, elem) = replicate n elem
Or, if you are familiar with currying:
func :: [(Int, a)] -> [a]
func xs = concat $ map (uncurry replicate) xs
Finally, if you are comfortable using function composition, the definition becomes:
func :: [(Int, a)] -> [a]
func = concat . map (uncurry replicate)
Using concat and map is so common, there is a function to do just that. It's concatMap.
func :: [(Int, a)] -> [a]
func = concatMap (uncurry replicate)

Let
ls = [(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')]
in
concat [replicate i x | (i, x) <- ls]
will give
"aaaabccaadeeee"
The point-free version
concat . map (uncurry replicate)

You are correct about trying to use map. But first lets see why your code did not work
replicate (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))
Your first parameter to replicate is the head of your list which is (4, 'a'). Then you are calling fst on this, thus the first parameter is 4. Same things happens with second parameter and you get 'a'. The result of which you see.
Before using map lets try to do this with recursion. You want to take one element of list and apply replicate to it and then combine it with the result of applying replicate on the second element.
generate [] = []
generate (x:xs) = replicate (fst x) (snd x) ++ generate xs
Do note I am using pattern matching to get the first element of list. You can us the pattern matching to get the element inside the tuple as well, and then you would not need to use the fst/snd functions. Also note I am using pattern matching to define the base case of empty list.
generate [] = []
generate ((x,y):xs) = replicate x y ++ generate xs
Now coming to map, so map will apply your function to every element of the list, here's the first try
generate (x,y) = replicate x y
map generate xs
The result of the above will be slightly different from recursion. Think about it, map is going to apply generate to every element and store the result in a list. generate creates a list. So when you apply map you are creating a list of list. You can use concat to flatten it if you want, which will give you the same result as recursion.
Last thing, if you can use recursion, then you can use fold as well. Fold will just apply a function to every element of the list and return the accumulated results (broadly speaking).
--first parameter is the function to apply, second is the accumulator, third is your list
foldr step [] xs
where step (x,y) acc =
(replicate x y) ++ acc
Again here I have used pattern matching in the function step to extract the elements of the tuple out.

Related

How do I filter a list without using List.filter in OCaml?

I have to write a function that, given two lists, it returns a list of the elements of the first one whose square is present in the second one (sry for my english). I can't do it recursively and i can't use List.filter.
this is what i did:
let lst1= [1;2;3;4;5];;
let lst2= [9;25;10;4];;
let filquadi lst1 lst2 =
let aux = [] in
List.map(fun x -> if List.mem (x*x) lst2 then x::aux else []) lst1;;
It works but it also prints [] when the number doesn't satisfy the if statement:
filquadi lst1 lst2 ;;
- : int list list = [[]; [2]; [3]; []; [5]]
how can I return a list of numbers instead of a list of a list of numbers?
- : int list = [2;3;5]
You can use List.concat to put things together at the end:
List.concat (List.map ...)
As a side comment, aux isn't doing anything useful in your code. It's just a name for the empty list (since OCaml variables are immutable). It would probably be clearer just to use [x] instead of x :: aux.
As another side comment, this is a strange sounding assignment. Normally the reason to forbid use of functions from the List module is to encourage you to write your own recursive solution (which indeed is educational). I can't see offhand a reason to forbid the use of recursion, but it's interesting to combine functions from List in different ways.
Your criteria don't say you can't use List.fold_left or List.rev, so...
let filter lst1 lst2 =
List.fold_left
(fun init x ->
if List.mem (x * x) lst2 then x::init
else init)
[] lst1
|> List.rev
We start with an empty list, and as we fold over the first list, add the current element only if that element appears in the second list. Because this results in a list that's reversed from its original order, we then reverse that.
If you're not supposed to use recursion, this is technically cheating, because List.fold_left works recursively, but then so does basically anything working with lists. Reimplementing the List module's functions is going to involve a lot of recursion, as can be seen from reimplementing fold_left and filter.
let rec fold_left f init lst =
match lst with
| [] -> init
| x::xs -> fold_left f (f init x) xs
let rec filter f lst =
match lst with
| [] -> []
| x::xs when f x -> x :: filter f xs
| _::xs -> filter f xs

Creating a lists of lists with new element in each position

i'm new in the haskell world and i'd like to know how to insert a value in each position of a list in haskell, and return a lists of sublists containing the value in each position. For example:
insert' :: a -> [a] -> [[a]]
insert' a [] = [[a]]
insert' a list = ??
To get something like:
insert' 7 [1,2,3] = [[7,1,2,3],[1,7,2,3],[1,2,7,3],[1,2,3,7]]
insert' :: a -> [a] -> [[a]]
insert' y [] = [[y]]
insert' y xss#(x:xs) = (y : xss) : map (x :) (insert' y xs)
While the empty list case comes natural, let's take a look at insert' y xss#(x:xs). We essentially have two cases we need to cover:
y appears in front of x. Then we can just use y : xss.
y appears somewhere after x. We therefore just insert it in the rest of our list and make sure that x is the first element with map (x:).
Although #delta's answer is definitely more elegant, here a solution with difference lists. If we insert an element x on every location of list ys = [y1,y2,...,yn], the first time we will insert it as head, so that means we can construct x : ys.
. For the second element of the resulting list, we want to construct a list [y1,x,y2,...,yn]. We can do this like y1 : x : y2s. The next lists will all have a structure y1 : ....
The question is: how can we write a recursive structure that keeps track of the fact that we want to put elements in the head. We can use a function for that: we start with a function id. If we now call id (x:ys) then we will of course generate the list (x:ys).
We can however, based on the id function, construct a new function id2 = \z -> id (y1:z). This function will thus put y1 in the head of the list and then add the list with which we call id2 as tail. Next we can construct id3 = \z -> id2 (y2:z). This will put y1 and y2 as first elements followed by the tail z.
So we can put this into the following recursive format:
insert' :: a -> [a] -> [[a]]
insert' x = go id
where go d [] = [d [x]]
go d ys#(yh:yt) = (d (x : ys)) : go (d . (yh :)) yt
So we redirect insert' to go where the initial difference list is simply the id function. Each time we check if we have reached the end of the given list. If that is the case, we return the basecase: we call [x] (as tail) on the difference list, and thus construct a list where we append x as last element.
In case we have not yet reached the last element, we will first emit d (x : ys): we prepend x to the list and provide this as argument to the difference list d. d will prepend y1 : y2 : ... : yk up to the point where we insert x. Furthermore we call recursively go (d . (yh :)) yt on the tail of the list: we thus construct a new difference list, wehere we insert (yh :) as tail of the list. We thus produce a new function with one argument: the tail after the yh element.
This function produces the expected results:
*Main> insert' 4 []
[[4]]
*Main> insert' 4 [1,2,5]
[[4,1,2,5],[1,4,2,5],[1,2,4,5],[1,2,5,4]]
*Main> insert' 7 [1,2,3]
[[7,1,2,3],[1,7,2,3],[1,2,7,3],[1,2,3,7]]
You may also do as follows;
import Data.List
spread :: a -> [a] -> [[a]]
spread x xs = zipWith (++) (inits xs) ((x:) <$> tails xs)
*Main> spread 7 [1,2,3]
[[7,1,2,3],[1,7,2,3],[1,2,7,3],[1,2,3,7]]
*Main> spread 7 []
[[7]]
So this is about three stages.
(x:) <$> tails xs is all about applying the (x:) function to all elements of tails xs function. So tails [1,2,3] would return [[1,2,3],[2,3],[3],[]] and we are to apply an fmap which is designated by <$> in the inline form. This is going to be the third argument of the zipWith function.
(inits xs) which would return [[],[1],[1,2],[1,2,3]], is going to be the second argument to zipWith.
zipWith (++) is obviously will zip two list of lists by concatenating the list elements.
So we may also express the same functionality with applicative function functors as follows;
spread :: a -> [a] -> [[a]]
spread x = zipWith (++) <$> inits <*> fmap (x:) . tails
In this case we fmap the zipWith (++) function with type [[a]] -> [[a]] -> [[a]] over inits and then apply it over to fmap (x:) . tails.
It could get more pointfree but becomes more complicated to read through (at least for me). In my opinion this is as best as it gets.

Haskell map list of tuples to list of tuples

I'm trying to map a list of tuples into a different list of tuples with no luck.
Example input:
a = [("eo","th"),("or","he")]
Example output:
[('e','t'),('o','h'),('o','h'),('r','e')]
I have tried:
map (\(a,b) -> (a!!0,b!!0):(a!!1,b!!1):[]) a
but it produces:
[[('e','t'),('o','h')],[('o','h'),('r','e')]]
You have to use concat on your result or use concatMap instead of map. After all, you return lists in your map and therefore get a list of lists.
Let's give your function a name and a type:
magic :: [([Char], [Char])] -> [(Char, Char)]
Now, we can think of this as a two-step process: from every pair in the original list we're going to get a list:
magicPair :: ([Char], [Char]) -> [(Char, Char)]
magicPair (a,b) = zip a b
Now we need to map magicPair over all elements in your original list and concatenate the result:
magic xs = concat (map magicPair xs)
The combination concat . map f is so common that there is a function called concatMap for this:
magic xs = concatMap magicPair xs
And using a function f on a pair instead of two arguments is also common, so magicPair = uncurry zip:
magic xs = concatMap (uncurry zip) xs
We can now remove xs on both sides to end up with the final variant of magic:
magic = concatMap (uncurry zip)
Here is a quick way to give you the output
simplify = (>>= uncurry zip)

How can I find the index where one list appears as a sublist of another?

I have been working with Haskell for a little over a week now so I am practicing some functions that might be useful for something. I want to compare two lists recursively. When the first list appears in the second list, I simply want to return the index at where the list starts to match. The index would begin at 0. Here is an example of what I want to execute for clarification:
subList [1,2,3] [4,4,1,2,3,5,6]
the result should be 2
I have attempted to code it:
subList :: [a] -> [a] -> a
subList [] = []
subList (x:xs) = x + 1 (subList xs)
subList xs = [ y:zs | (y,ys) <- select xs, zs <- subList ys]
where select [] = []
select (x:xs) = x
I am receiving an "error on input" and I cannot figure out why my syntax is not working. Any suggestions?
Let's first look at the function signature. You want to take in two lists whose contents can be compared for equality and return an index like so
subList :: Eq a => [a] -> [a] -> Int
So now we go through pattern matching on the arguments. First off, when the second list is empty then there is nothing we can do, so we'll return -1 as an error condition
subList _ [] = -1
Then we look at the recursive step
subList as xxs#(x:xs)
| all (uncurry (==)) $ zip as xxs = 0
| otherwise = 1 + subList as xs
You should be familiar with the guard syntax I've used, although you may not be familiar with the # syntax. Essentially it means that xxs is just a sub-in for if we had used (x:xs).
You may not be familiar with all, uncurry, and possibly zip so let me elaborate on those more. zip has the function signature zip :: [a] -> [b] -> [(a,b)], so it takes two lists and pairs up their elements (and if one list is longer than the other, it just chops off the excess). uncurry is weird so lets just look at (uncurry (==)), its signature is (uncurry (==)) :: Eq a => (a, a) -> Bool, it essentially checks if both the first and second element in the pair are equal. Finally, all will walk over the list and see if the first and second of each pair is equal and return true if that is the case.

Apply "permutations" of a function over a list

Creating the permutations of a list or set is simple enough. I need to apply a function to each element of all subsets of all elements in a list, in the order in which they occur. For instance:
apply f [x,y] = { [x,y], [f x, y], [x, f y], [f x, f y] }
The code I have is a monstrous pipeline or expensive computations, and I'm not sure how to proceed, or if it's correct. I'm sure there must be a better way to accomplish this task - perhaps in the list monad - but I'm not sure. This is my code:
apply :: Ord a => (a -> Maybe a) -> [a] -> Set [a]
apply p xs = let box = take (length xs + 1) . map (take $ length xs) in
(Set.fromList . map (catMaybes . zipWith (flip ($)) xs) . concatMap permutations
. box . map (flip (++) (repeat Just)) . flip iterate []) ((:) p)
The general idea was:
(1) make the list
[[], [f], [f,f], [f,f,f], ... ]
(2) map (++ repeat Just) over the list to obtain
[[Just, Just, Just, Just, ... ],
[f , Just, Just, Just, ... ],
[f , f , Just, Just, ... ],
... ]
(3) find all permutations of each list in (2) shaved to the length of the input list
(4) apply the permuted lists to the original list, garnering all possible applications
of the function f to each (possibly empty) subset of the original list, preserving
the original order.
I'm sure there's a better way to do it, though. I just don't know it. This way is expensive, messy, and rather prone to error. The Justs are there because of the intended application.
To do this, you can leverage the fact that lists represent non-deterministic values when using applicatives and monads. It then becomes as simple as:
apply f = mapM (\x -> [x, f x])
It basically reads as follows: "Map each item in a list to itself and the result of applying f to it. Finally, return a list of all the possible combinations of these two values across the whole list."
If I understand your problem correctly, it's best not to describe it in terms of permutations. Rather, it's closer to generating powersets.
powerset (x:xs) = let pxs = powerset xs in pxs ++ map (x :) pxs
powerset [] = [[]]
Each time you add another member to the head of the list, the powerset doubles in size. The second half of the powerset is exactly like the first, but with x included.
For your problem, the choice is not whether to include or exclude x, but whether to apply or not apply f.
powersetapp f (x:xs) = let pxs = powersetapp f xs in map (x:) pxs ++ map (f x:) pxs
powersetapp f [] = [[]]
This does what your "apply" function does, modulo making a Set out of the result.
Paul's and Heatsink's answers are good, but error out when you try to run them on infinite lists.
Here's a different method that works on both infinite and finite lists:
apply _ [] = [ [] ]
apply f (x:xs) = (x:ys):(x':ys):(double yss)
where x' = f x
(ys:yss) = apply f xs
double [] = []
double (ys:yss) = (x:ys):(x':ys):(double yss)
This works as expected - though you'll note it produces a different order to the permutations than Paul's and Heatsink's
ghci> -- on an infinite list
ghci> map (take 4) $ take 16 $ apply (+1) [0,0..]
[[0,0,0,0],[1,0,0,0],[0,1,0,0],[1,1,0,0],[0,0,1,0],...,[1,1,1,1]]
ghci> -- on a finite list
ghci> apply (+1) [0,0,0,0]
[[0,0,0,0],[1,0,0,0],[0,1,0,0],[1,1,0,0],[0,0,1,0],...,[1,1,1,1]]
Here is an alternative phrasing of rampion's infinite-input-handling solution:
-- sequence a list of nonempty lists
sequenceList :: [[a]] -> [[a]]
sequenceList [] = [[]]
sequenceList (m:ms) = do
xs <- nonempty (sequenceList ms)
x <- nonempty m
return (x:xs)
where
nonempty ~(x:xs) = x:xs
Then we can define apply in Paul's idiomatic style:
apply f = sequenceList . map (\x -> [x, f x])
Contrast sequenceList with the usual definition of sequence:
sequence :: (Monad m) => [m a] -> m [a]
sequence [] = [[]]
sequence (m:ms) = do
x <- m
xs <- sequence ms
return (x:xs)
The order of binding is reversed in sequenceList so that the variations of the first element are the "inner loop", i.e. we vary the head faster than the tail. Varying the end of an infinite list is a waste of time.
The other key change is nonempty, the promise that we won't bind an empty list. If any of the inputs were empty, or if the result of the recursive call to sequenceList were ever empty, then we would be forced to return an empty list. We can't tell in advance whether any of inputs is empty (because there are infinitely many of them to check), so the only way for this function to output anything at all is to promise that they won't be.
Anyway, this is fun subtle stuff. Don't stress about it on your first day :-)