List.map on columns instead of rows in OCaml - list

Say I have the following 'a list list:
[[a1 ; a2 ; a3];[b1 ; b2 ; b3] ;[c1 ; c2 ; c3]]
Is there a way to apply a function f to elements of that list to produce the following using List.map?
[ f [a1; b1; c1]; f [a2; b2; c2]; f [a3; b3; c3]]
I know that List.map iterates through every element of my 'a list list, but it applies the function f on every 'a list (row) in my 'a list list instead of every column of my 'a list list

Well, the columns don't exist as values in your data. You might say they exist more as an idea. So there's nothing in the data you can pass to f to get your desired result.
You can, of course, create the lists representing the columns and then apply f to those.
If your list represents a matrix, you want a list that represents the transpose of the matrix. So one way to proceed would be to write a function to transpose your matrix, then apply List.map to that.

In addition to Jeffrey Scofields answer, below is a definition for a transpose_map function.
(**
Returns a list of list. The i-th element is a list whose first element is
the i-th element of xs followed by the i-th element of ys.
For
xs = [ x1; x2; ...]
ys = [ [y11; y12; ... ]; [ y21; y22; ... ]; ... ]
the function gives
[ [ x1; y11; y12; ... ]; [ x2; y21; y22; ...]; ... ]
.
*)
let rec list_cons xs ys =
List.map2 (fun x zs -> x :: zs) xs ys
(** Compute the transpose of a list of list. *)
let rec transpose m =
match m with
| [] -> []
| [a] -> List.map (fun x -> [x]) a
| hd :: tl -> list_cons hd (transpose tl)
(** Apply a function to the columns of a matrix and return the list of
transformed columns. *)
let transpose_map f xs = List.map f (transpose xs)

Related

Haskell How to rewrite a code using fold-function?

I want to rewrite (or upgrade! :) ) my two functions, hist and sort, using fold-functions. But since I am only in the beginning of my Haskell-way, I can't figure out how to do it.
First of all, I have defined Insertion, Table and imported Data.Char:
type Insertion = (Char, Int)
type Table = [Insertion]
import Data.Char
Then I have implemented the following code for hist:
hist :: String -> Table
hist[] = []
hist(x:xs) = sortBy x (hist xs) where
sortBy x [] = [(x,1)]
sortBy x ((y,z):yzs)
| x == y = (y,z+1) : yzs
| otherwise = (y,z) : sortBy x yzs
And this one for sort:
sort :: Ord a => [a] -> [a]
sort [] = []
sort (x:xs) = paste x (sort xs)
paste :: Ord a => a -> [a] -> [a]
paste y [] = [y]
paste y (x:xs)
| x < y = x : paste y xs
| otherwise = y : x : xs
What can I do next? How can I use the fold-functions to implement them?
foldr f z on a list replaces the "cons" of the list (:) with f and the empty list [] with z.
This thus means that for a list like [1,4,2,5], we thus obtain f 1 (f 4 (f 2 (f 5 z))), since [1,4,2,5] is short for 1 : 4 : 2 : 5 : [] or more canonical (:) 1 ((:) 4 ((:) 2 ((:) 5 []))).
The sort function for example can be replaced with a fold function:
sort :: Ord a => [a] -> [a]
sort = foldr paste []
since sort [1,4,2,5] is equivalent to paste 1 (paste 4 (paste 2 (paste 5 []))). Here f thus takes as first parameter an element, and as second parameter the result of calling foldr f z on the rest of the list,
I leave hist as an exercise.

Multiplying Lists through Folding

So I am currently trying to figure out how to write a function where it takes 2 lists of equal lengths and multiplies the same position of both lists through folding, and returns the result as a new List.
eg) let prodList [1; 2; 3] [4; 5; 6] ;;
==> (through folding) ==> [1*4; 2*5; 3*6]
==> result = [4; 10; 18]
I feel like I need to use List.combine, since it will put the values that need to be multiplied into tuples. After that, I can't figure out how to break apart the tuple in a way that allows me to multiply the values. Here is what I have so far:
let prodLists l1 l2 =
let f a x = (List.hd(x)) :: a in
let base = [] in
let args = List.rev (List.combine l1 l2) in
List.fold_left f base args
Am I on the right track?
You can use fold_left2 which folds two lists of the same length. The documentation can give you more details (https://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html):
val fold_left2 : ('a -> 'b -> 'c -> 'a) -> 'a -> 'b list -> 'c list -> 'a
List.fold_left2 f a [b1; ...; bn] [c1; ...; cn] is f (... (f (f a b1 c1) b2 c2) ...) bn cn. Raise Invalid_argument if the two lists are determined to have different lengths.
Another way is to fold the output of combine as you have suggested, I would recommend you to try it by yourself before looking at the solution bellow.
Solution:
let prod_lists l s =
List.rev (List.fold_left2 (fun acc a b -> (a * b) :: acc) [] l s);;
let prod_lists' l s =
List.fold_left (fun acc (a, b) -> (a * b) :: acc) [] (List.rev (List.combine l s));;
First let me note using fold to implement this operation seems a bit forced, since you have to traverse both lists at the same time. Fold however combines the elements of a single list. Nonetheless here is an implementation.
let e [] = []
let f x hxs (y::ys) = (x*y) :: hxs ys
let prodList xs ys = List.fold_right f xs e ys
Looks a bit complicated, so let me explain.
Universal Property of fold right
First you should be aware of the following property of fold_right.
h xs = fold_right f xs e
if and only if
h [] = e
h (x::xs) = f x (h xs)
This means that if we write the multiplication of lists in the recursive form below, then we can use the e and f to write it using fold as above. Note though we are operating two lists so h takes two arguments.
Base case - empty lists
Multiplying two empty lists returns an empty list.
h [] [] = []
How to write this in the form above? Just abstract over the second argument.
h [] = fun [] -> []
So,
e = fun [] -> []`
Or equivalently,
e [] = []
Recursive case - non-empty lists
h (x::xs) (y::ys) = x*y :: h xs ys
Or, using just one argument,
h (x::xs) = fun -> (y::ys) -> x*y :: h xs ys
Now we need to rewrite this expression in the form h (x::xs) = f x (h xs). It may seem complicated but we just need to abstract over x and h xs.
h (x::xs) = (fun x hxs -> fun (y::ys) -> x*y :: hxs ys) x (h xs)
so we have that f is defined by,
f = fun x hxs -> fun (y::ys) -> x*y :: hxs ys
or equivalently,
f x hxs (y::ys) = x*y :: hxs ys
Solution as a fold right
Having determined both e and f we just plug then into fold according to the first equation of the property above. And we get,
h xs = List.fold_right f xs e
or equivalently,
h xs ys = List.fold_right f xs e ys
Understanding the implementation
Note that the type of List.fold_right f xs e is int list -> int list, so the fold is building a function on lists, that given some ys will multiply it with the given parameter xs.
For an empty xs you will expect an empty ys and return an empty result so,
e [] = fun [] -> []
As for the recursive case, the function f in a fold_right must implement a solution for x::xs from a solution for xs. So f takes an x of type int and a function hxs of type int list -> int list which implements the multiplication for the tail, and it must implement multiplication for x::xs.
f x hxs = fun (y::ys) -> x*y :: hxs ys
So f constructs a function that multiplies x with y, and then applies to ys the already constructed hxs which multiplies xs to a list.
You mostly have the right idea; you'll want to combine (zip in other languages) the two lists and then map over each tuple:
let prod_lists l1 l2 =
List.combine l1 l2
|> List.map (fun (a, b) -> a * b)
The key is that you can pattern match on that tuple using (a, b).
You can also fold over the combined list, then rev the result, if you don't want to use map.

Haskell: How to update each infinite variable once in list comprehension using infinite lists [duplicate]

I wish to produce the Cartesian product of 2 lists in Haskell, but I cannot work out how to do it. The cartesian product gives all combinations of the list elements:
xs = [1,2,3]
ys = [4,5,6]
cartProd :: [a] -> [b] -> [(a,b)]
cartProd xs ys ==> [(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]
This is not an actual homework question and is not related to any such question, but the way in which this problem is solved may help with one I am stuck on.
This is very easy with list comprehensions. To get the cartesian product of the lists xs and ys, we just need to take the tuple (x,y) for each element x in xs and each element y in ys.
This gives us the following list comprehension:
cartProd xs ys = [(x,y) | x <- xs, y <- ys]
As other answers have noted, using a list comprehension is the most natural way to do this in Haskell.
If you're learning Haskell and want to work on developing intuitions about type classes like Monad, however, it's a fun exercise to figure out why this slightly shorter definition is equivalent:
import Control.Monad (liftM2)
cartProd :: [a] -> [b] -> [(a, b)]
cartProd = liftM2 (,)
You probably wouldn't ever want to write this in real code, but the basic idea is something you'll see in Haskell all the time: we're using liftM2 to lift the non-monadic function (,) into a monad—in this case specifically the list monad.
If this doesn't make any sense or isn't useful, forget it—it's just another way to look at the problem.
If your input lists are of the same type, you can get the cartesian product of an arbitrary number of lists using sequence (using the List monad). This will get you a list of lists instead of a list of tuples:
> sequence [[1,2,3],[4,5,6]]
[[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]]
There is a very elegant way to do this with Applicative Functors:
import Control.Applicative
(,) <$> [1,2,3] <*> [4,5,6]
-- [(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]
The basic idea is to apply a function on "wrapped" arguments, e.g.
(+) <$> (Just 4) <*> (Just 10)
-- Just 14
In case of lists, the function will be applied to all combinations, so all you have to do is to "tuple" them with (,).
See http://learnyouahaskell.com/functors-applicative-functors-and-monoids#applicative-functors or (more theoretical) http://www.soi.city.ac.uk/~ross/papers/Applicative.pdf for details.
Other answers assume that the two input lists are finite. Frequently, idiomatic Haskell code includes infinite lists, and so it is worthwhile commenting briefly on how to produce an infinite Cartesian product in case that is needed.
The standard approach is to use diagonalization; writing the one input along the top and the other input along the left, we could write a two-dimensional table that contained the full Cartesian product like this:
1 2 3 4 ...
a a1 a2 a3 a4 ...
b b1 b2 b3 b4 ...
c c1 c2 c3 c4 ...
d d1 d2 d3 d4 ...
. . . . . .
. . . . . .
. . . . . .
Of course, working across any single row will give us infinitely elements before it reaches the next row; similarly going column-wise would be disastrous. But we can go along diagonals that go down and to the left, starting again in a bit farther to the right each time we reach the edge of the grid.
a1
a2
b1
a3
b2
c1
a4
b3
c2
d1
...and so on. In order, this would give us:
a1 a2 b1 a3 b2 c1 a4 b3 c2 d1 ...
To code this in Haskell, we can first write the version that produces the two-dimensional table:
cartesian2d :: [a] -> [b] -> [[(a, b)]]
cartesian2d as bs = [[(a, b) | a <- as] | b <- bs]
An inefficient method of diagonalizing is to then iterate first along diagonals and then along depth of each diagonal, pulling out the appropriate element each time. For simplicity of explanation, I'll assume that both the input lists are infinite, so we don't have to mess around with bounds checking.
diagonalBad :: [[a]] -> [a]
diagonalBad xs =
[ xs !! row !! col
| diagonal <- [0..]
, depth <- [0..diagonal]
, let row = depth
col = diagonal - depth
]
This implementation is a bit unfortunate: the repeated list indexing operation !! gets more and more expensive as we go, giving quite a bad asymptotic performance. A more efficient implementation will take the above idea but implement it using zippers. So, we'll divide our infinite grid into three shapes like this:
a1 a2 / a3 a4 ...
/
/
b1 / b2 b3 b4 ...
/
/
/
c1 c2 c3 c4 ...
---------------------------------
d1 d2 d3 d4 ...
. . . . .
. . . . .
. . . . .
The top left triangle will be the bits we've already emitted; the top right quadrilateral will be rows that have been partially emitted but will still contribute to the result; and the bottom rectangle will be rows that we have not yet started emitting. To begin with, the upper triangle and upper quadrilateral will be empty, and the bottom rectangle will be the entire grid. On each step, we can emit the first element of each row in the upper quadrilateral (essentially moving the slanted line over by one), then add one new row from the bottom rectangle to the upper quadrilateral (essentially moving the horizontal line down by one).
diagonal :: [[a]] -> [a]
diagonal = go [] where
go upper lower = [h | h:_ <- upper] ++ case lower of
[] -> concat (transpose upper')
row:lower' -> go (row:upper') lower'
where upper' = [t | _:t <- upper]
Although this looks a bit more complicated, it is significantly more efficient. It also handles the bounds checking that we punted on in the simpler version.
But you shouldn't write all this code yourself, of course! Instead, you should use the universe package. In Data.Universe.Helpers, there is (+*+), which packages together the above cartesian2d and diagonal functions to give just the Cartesian product operation:
Data.Universe.Helpers> "abcd" +*+ [1..4]
[('a',1),('a',2),('b',1),('a',3),('b',2),('c',1),('a',4),('b',3),('c',2),('d',1),('b',4),('c',3),('d',2),('c',4),('d',3),('d',4)]
You can also see the diagonals themselves if that structure becomes useful:
Data.Universe.Helpers> mapM_ print . diagonals $ cartesian2d "abcd" [1..4]
[('a',1)]
[('a',2),('b',1)]
[('a',3),('b',2),('c',1)]
[('a',4),('b',3),('c',2),('d',1)]
[('b',4),('c',3),('d',2)]
[('c',4),('d',3)]
[('d',4)]
If you have many lists to product together, iterating (+*+) can unfairly bias certain lists; you can use choices :: [[a]] -> [[a]] for your n-dimensional Cartesian product needs.
Yet another way to accomplish this is using applicatives:
import Control.Applicative
cartProd :: [a] -> [b] -> [(a,b)]
cartProd xs ys = (,) <$> xs <*> ys
Yet another way, using the do notation:
cartProd :: [a] -> [b] -> [(a,b)]
cartProd xs ys = do x <- xs
y <- ys
return (x,y)
The right way is using list comprehensions, as other people have already pointed out, but if you wanted to do it without using list comprehensions for any reason, then you could do this:
cartProd :: [a] -> [b] -> [(a,b)]
cartProd xs [] = []
cartProd [] ys = []
cartProd (x:xs) ys = map (\y -> (x,y)) ys ++ cartProd xs ys
Well, one very easy way to do this would be with list comprehensions:
cartProd :: [a] -> [b] -> [(a, b)]
cartProd xs ys = [(x, y) | x <- xs, y <- ys]
Which I suppose is how I would do this, although I'm not a Haskell expert (by any means).
something like:
cartProd x y = [(a,b) | a <- x, b <- y]
It's a job for sequenceing. A monadic implementation of it could be:
cartesian :: [[a]] -> [[a]]
cartesian [] = return []
cartesian (x:xs) = x >>= \x' -> cartesian xs >>= \xs' -> return (x':xs')
*Main> cartesian [[1,2,3],[4,5,6]]
[[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]]
As you may notice, the above resembles the implementation of map by pure functions but in monadic type. Accordingly you can simplify it down to
cartesian :: [[a]] -> [[a]]
cartesian = mapM id
*Main> cartesian [[1,2,3],[4,5,6]]
[[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]]
Just adding one more way for the enthusiast, using only recursive pattern matching.
cartProd :: [a]->[b]->[(a,b)]
cartProd _ []=[]
cartProd [] _ = []
cartProd (x:xs) (y:ys) = [(x,y)] ++ cartProd [x] ys ++ cartProd xs ys ++ cartProd xs [y]
Here is my implementation of n-ary cartesian product:
crossProduct :: [[a]] -> [[a]]
crossProduct (axis:[]) = [ [v] | v <- axis ]
crossProduct (axis:rest) = [ v:r | v <- axis, r <- crossProduct rest ]
Recursive pattern matching with out List comprehension
crossProduct [] b=[]
crossProduct (x : xs) b= [(x,b)] ++ crossProduct xs b
cartProd _ []=[]
cartProd x (u:uv) = crossProduct x u ++ cartProd x uv
If all you want is the Cartesian product, any of the above answers will do. Usually, though, the Cartesian product is a means to an end. Usually, this means binding the elements of the tuple to some variables, x and y, then calling some function f x y on them. If this is the plan anyway, you might be better off just going full monad:
do
x <- [1, 2]
y <- [6, 8, 10]
pure $ f x y
This will produce the list [f 1 6, f 1 8, f 1 10, f 2 6, f 2 8, f 2 10].

Combining a column of lists in OCaml

I want to essentially transpose a matrix in OCaml (without using recursion or any sort of looping)
For example, if I have the following matrix: [[1;2];[3;4]],
I want to have the output of [[1;3];[2;4]].
What I have done so far is break the original matrix into individual columns:
//function that separates into cols
let separate li =
List.map (fun x -> [x]) li;;
I call this helper function from another function:
let trans x =
List.concat (List.map separate li) x;;
I was thinking this would combine all the columns the way I want to but rather, ended with the following output: [[1];[2];[3];[4]].
I question whether your separate function separates the matrix into columns. Here's what I see:
# let separate li = List.map (fun x -> [x]) li;;
val separate : 'a list -> 'a list list = <fun>
# List.map separate [[1;2];[3;4]];;
- : int list list list = [[[1]; [2]]; [[3]; [4]]]
I don't see columns, I just see that you've put each matrix element into its own list.
To get the first column you could try this:
# List.map List.hd [[1;2]; [3;4]];;
- : int list = [1; 3]
If you use List.tl rather than List.hd you get the remainders of the rows. Maybe you can use a fold to apply this repeatedly and collect up the results.
Assuming your list of lists is rectangular, this Standard ML code translates to OCaml as such:
let rec transpose xss =
match xss with
| [] -> []
| []::_ -> []
| _ -> List.map List.hd xss :: transpose (List.map List.tl xss)
It extracts the first column (List.map List.hd xss) and recursively combines it with the extraction of the remaining columns, after having removed the already extracted column (List.map List.tl xss).
The explicit recursion that still remains in this function cannot easily be replaced by mapping / folding, since those would address one row at a time, where the recursion scheme above addresses (a part of) all rows at once. You might have more luck with unfolding / anamorphism:
let rec unfold f a =
match f a with
| Some (b, a') -> b :: unfold f a'
| None -> []
val unfold : ('a -> ('b * 'a) option) -> 'a -> 'b list = <fun>
where 'a could be the gradual reduction of your input row matrix, and 'b the matrix columns:
let transpose =
unfold (function
| [] -> None
| []::_ -> None
| m -> Some (List.map List.hd m, List.map List.tl m))

How do I use List.map to apply a function on a int list list?

Suppose I have a (int list list) x = [[1;1;1]; [2;2;2]; [3;4;5]] and a function f. The result should be [f [1;1;1]; f [2;2;2]; f[3;4;5]]. The built in List.map works only for int list but not for int list list.The i-th entry in this new column is computed by the function f which is taking as input the i-th element from each column in the spreadsheet and forms a new element.
let newList x f = List.map f x (* this is the only map function that I know *)
You can use List.map f as a function, which works on one dimensional lists, and then map that function on the two-dimensional list as follows:
let x = [[1;1;1]; [2;2;2]; [3;4;5]];;
let f x = x + 1;;
List.map (List.map f) x;;
output:
- : int list list = [[2; 2; 2]; [3; 3; 3]; [4; 5; 6]]
my function will take as input two arguments, an int list list and a
function f. It will output a new int list. Input = m = [[x1;x2;x3] ;
[y1;y2;y3] ; [z1;z2;z3]] and function f Output = [f [x1;y1;z1] ; f
[x2;y2;z2] ; f [x3;y3;z3]]
It seems that you wanted to transpose (https://stackoverflow.com/a/3989823/4196578) your 2-D array and then map f. In that case, you can do:
let rec transpose list = match list with
| [] -> []
| [] :: xss -> transpose xss
| (x::xs) :: xss ->
(x :: List.map List.hd xss) :: transpose (xs :: List.map List.tl xss);;
let myfunc m f = List.map f (transpose m);;