How to use List.fold_left ocaml with multiple arguments? - functional-programming

So I have a function like so
let test (item: 'a ) (factors: items) : ('b list) =
....
This function takes in an item of some 'a elements and my own items type, which is another list of items I pass to it. I return a list of a different type later after doing some stuff
How do I use List.fold_left with this function so that if I have a list of 'a items, I can just apply test to each one individually, and pass 'factors' to all of them, and then so that I can concatenate the resultant 'b type lists for each one.
For example, the I would need to process the following list:
[somea; someb; somec]
as
(test somea factors)#(test someb factors)#(test somec factors)
Is this a task that List.fold_left is not applicable for? Is there some other function I can use? I can't recursively traverse and call the function because of some mutually-recursive problems going on with the other methods in my code so is there another way? Would List.map be useful here instead?

For this particular purpose, things would go better if factors was the first parameter of test. Let's call this function fliptest:
let fliptest a b = test b a
So then your function looks like this (it seems to me):
let process factors list =
List.concat (List.map (fliptest factors) list)
(If this isn't quite right, it's probably close.)

Related

Calculating the Trace of a Matrix; Syntactical Errors

I was tasked with writing OCAML code to calculate the Trace of a square matrix (the values inside the diagonal of a matrix). As a bonus, and for my own understanding, I'd also like to write code to produce a list of the trace of a square matrix.
I've created a tail recursive function utilizing the List.map feature which strips the first element of each row, and so on and so forth.
let trace m =
let rec helper m acc =
match m with
|[] -> acc
|(x::_) -> helper(List.map(fun(y::ys) -> ys)) (acc+x)
in helper m 0 ;;
Unfortunately I believe my syntax is off and I am unsure how to go about solving this. I think I have the right theory/idea in mind but poor implementation. Any help would be greatly appreciated
This is the error I get when I run the code:
This expression has type 'a list list -> 'a list list but an expression was expected of type 'b list
1:Warning 8: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
[]
As #glennsl says, you should do the work to ask a good question. You don't tell us anything about the error you see, for example. Generally you should copy/paste the error text into your question.
When I copy/paste your code I see an error for this fragment:
(List.map (fun (y :: ys) -> ys))
List.map takes two parameters: the first is a function, which you have. The second is a list to map over, which you don't have here. Since you don't supply a list, the value of this expression is a function that expects a list and returns the transformed list.
Since the first parameter of helper is a list of lists (I assume), and not a function, you have a type error. (Not a syntax error.)
Most likely you need to supply the list over which you want to map your function.

How do I create a function which reverses an int list in OCaml?

I have a type intlist:
type intlist = Nil | Cons of int * intlist
and I'd now like to write a function that reverses the list. I have no real idea how to go about this. in class, our prof defined a function within a function, I believe, but I don't have the solution with me. How would one do this, simply? I would appreciate if we can keep the coding rather rudimentary, seeing as I'm relatively new to this.
So far, I only have
let reverse (l : intlist) : intlist =
match l with
Nil -> Nil
| Cons(a, Nil) -> Cons(a, Nil)
This is how I tend to create these kinds of functions, so I've written the trivial part (which granted, may not actually be what I need to start with). Any help is appreciated, thanks!
You indeed need a helper function, since for the reversing you need to build another list, so you need a function that will recurse into one list, while building another list, i.e., that has two arguments. In fact, this helper function is called rev_append and it is appending a reversed contents of one list to another. But let's try to make it using a helper function defined in the scope of the rev function:
let rev xs =
let rec loop xs ys = match xs with
| Nil -> ys
| Cons (x,xs) -> loop xs (Cons (x,ys)) in
loop xs Nil
So, to reverse a list we just take each element of a list and put it into another list. Since list behaves like a stack we are getting the reversed list for free. It is like Hanoi towers, when you pick elements from one list (tower) and put them to another, they will end up in a reversed order.

Function calling for each element in a list

Using only recursion (ie. no loops of any sort), given a list of elements, how can I call a function each time for every element of the list using that element as an argument each time in OCaml? Fold and map would not work because although they are applying a function to each element, it returns a list of whatever function I called on each element, which is not what I want.
To better illustrate what I'm essentially trying to do in OCaml, here's the idea of what I want in Ruby code:
arr.each {|x| some_function x}
but I must do this using only recursion and no iter functions
The correct recursive function is described as:
if the list is empty, do nothing;
else, process the first element and then the tail of the list.
The corresponding code is:
let rec do_all f lst =
match lst with
| [] -> ()
| x :: xs -> f x; do_all f xs
A fairly general template for a recursive function would be this:
let rec f x =
if x is trival to handle then
handle x
else
let (part, rest) = division of x into smaller parts in
let part_result = handle_part part in
let recursive_result = f rest in
combine part_result recursive_result
Since you don't need a result, you can skip a lot of this.
Which parts of this template seem most difficult to do for your problem?
Update
(As #EduardoLeĆ³n points out, when working with lists you can test for a trivial list and break down the list into smaller parts using pattern matching. Pattern matching is cool.)
Update 2
My question is sincere. Which part are you having trouble with? Otherwise we don't know what to suggest.

Curried Functions in Standard ML

I've been banging my head against the wall trying to learn about curried functions. Here's what I understand so far; suppose I have a function:
fun curry (a b c) = a * b * c;
or
fun curry a b c = a * b * c;
In ML, I can only have one argument so the first function uses a 3-tuple to get around this / get access to a, b, and c.
In the second example, what I really have is:
fun ((curry a) b) c
where curry a returns a function, and
(curry a) b returns a function and ((curry a) b) c returns another function. A few questions:
1) Why is this preferable to using a tuple? Is it just that I can make use of the intermediate functions curry a and (curry a) b. My book mentions partial instantiation but not totally clear on it.
2) How do you determine what function curry a, (curry a) b actually do? ((curry a) b) c is just a * b * c, right?
Thanks for any help clearing this up,
bclayman
There is an element of taste in using curried vs. non-curried functions. I don't use curried functions as a matter of course. For example, if were to write a gcd function I would tend to write it as a function designed to operated on a tuple simply because I seldom have use for a defined partially-instantiated gcd function.
Where curried functions are really useful is in defining higher-order functions. Consider map. It is easy enough to write a non-curried version:
fun mymap (f,[])= []
| mymap (f,x::xs) = f(x)::mymap(f,xs)
It has type fn : ('a -> 'b) * 'a list -> 'b list taking a tuple consisting of a function between two types and a list of elements of the input type, returning a list of element of the output type. There is nothing exactly wrong with this function, but -- it isn't the same as SML's map. The built-in map has type
fn : ('a -> 'b) -> 'a list -> 'b list
which is curried. What does the curried function do for us? For one thing, it can be thought of as a function transformer. You feed map a function, f, designed to operate on elements of a given type and it returns as function map f which is designed to operate on whole lists of elements. For example, if
fun square(x) = x*x;
Is a function designed to square ints then val list_square = map square defines list_square as a function which takes a list of elements and returns the list of their squares.
When you use map in a call like map square [1,2,3] you have to remember that function application is left associative so that this parses as
'(map square) [1,2,3]. The functionmap square*is* the same as the functionlist_squareI defined above. The invocationmap square [1,2,3]takes that function and applies it to[1,2,3]yielding[1,4,9]`.
The curried version is really nice if you want to define a function, metamap, which can be used to apply functions to each element of a matrix thought of as a list of lists. Using the curried version it is as simple as:
fun metamap f = map (map f)
used like (in the REPL):
- metamap square [[1,2],[3,4]];
val it = [[1,4],[9,16]] : int list list
The logic is that map lifts a function from applying to elements to applying to lists. If you want a function to apply to lists of lists (e.g. matrices) just apply map twice -- which is all metamap does. You could, of course, write a version a non-curried version of metamap using our noncurried mymap function (it wouldn't even be all that hard), but you wouldn't be able to approach the elegance of the 1-line definition above.

Confused over behavior of List.mapi in F#

I am building some equations in F#, and when working on my polynomial class I found some odd behavior using List.mapi
Basically, each polynomial has an array, so 3*x^2 + 5*x + 6 would be [|6, 5, 3|] in the array, so, when adding polynomials, if one array is longer than the other, then I just need to append the extra elements to the result, and that is where I ran into a problem.
Later I want to generalize it to not always use a float, but that will be after I get more working.
So, the problem is that I expected List.mapi to return a List not individual elements, but, in order to put the lists together I had to put [] around my use of mapi, and I am curious why that is the case.
This is more complicated than I expected, I thought I should be able to just tell it to make a new List starting at a certain index, but I can't find any function for that.
type Polynomial() =
let mutable coefficients:float [] = Array.empty
member self.Coefficients with get() = coefficients
static member (+) (v1:Polynomial, v2:Polynomial) =
let ret = List.map2(fun c p -> c + p) (List.ofArray v1.Coefficients) (List.ofArray v2.Coefficients)
let a = List.mapi(fun i x -> x)
match v1.Coefficients.Length - v2.Coefficients.Length with
| x when x < 0 ->
ret :: [((List.ofArray v1.Coefficients) |> a)]
| x when x > 0 ->
ret :: [((List.ofArray v2.Coefficients) |> a)]
| _ -> [ret]
I think that a straightforward implementation using lists and recursion would be simpler in this case. An alternative implementation of the Polynomial class might look roughly like this:
// The type is immutable and takes initial list as constructor argument
type Polynomial(coeffs:float list) =
// Local recursive function implementing the addition using lists
let rec add l1 l2 =
match l1, l2 with
| x::xs, y::ys -> (x+y) :: (add xs ys)
| rest, [] | [], rest -> rest
member self.Coefficients = coeffs
static member (+) (v1:Polynomial, v2:Polynomial) =
// Add lists using local function
let newList = add v1.Coefficients v2.Coefficients
// Wrap result into new polynomial
Polynomial(newList)
It is worth noting that you don't really need mutable field in the class, since the + operator creates and returns a new instance of the type, so the type is fully immutable (as you'd usually want in F#).
The nice thing in the add function is that after processing all elements that are available in both lists, you can simply return the tail of the non-empty list as the rest.
If you wanted to implement the same functionality using arrays, then it may be better to use a simple for loop (since arrays are, in principle, imperative, the usual imperative patterns are usually the best option for dealing with them). However, I don't think there is any particular reason for preferring arrays (maybe performance, but that would have to be evaluated later during the development).
As Pavel points out, :: operator appends a single element to the front of a list (see the add function above, which demonstrates that). You could write what you wanted using # which concatenates lists, or using Array.concat (which concatenates a sequence of arrays).
An implementation using higher-order functions and arrays is also possible - the best version I can come up with would look like this:
let add (a1:_[]) (a2:_[]) =
// Add parts where both arrays have elements
let l = min a1.Length a2.Length
let both = Array.map2 (+) a1.[0 .. l-1] a2.[0 .. l-1]
// Take the rest of the longer array
let rest =
if a1.Length > a2.Length
then a1.[l .. a1.Length - 1]
else a2.[l .. a2.Length - 1]
// Concatenate them
Array.concat [ both; rest ]
add [| 6; 5; 3 |] [| 7 |]
This uses slices (e.g. a.[0 .. l]) which give you a part of an array - you can use these to take the parts where both arrays have elements and the remaining part of the longer array.
I think you're misunderstanding what operator :: does. It's not used to concatenate two lists. It's used to prepend a single element to the list. Consequently, it's type is:
'a -> 'a list -> 'a list
In your case, you're giving ret as a first argument, and ret is itself a float list. Consequently, it expects the second argument to be of type float list list - hence why you need to add an extra [] to the second argument to make it to compile - and that will also be the result type of your operator +, which is probably not what you want.
You can use List.concat to concatenate two (or more) lists, but that is inefficient. In your example, I don't see the point of using lists at all - all this converting back & forth is going to be costly. For arrays, you can use Array.append, which is better.
By the way, it's not clear what is the purpose of mapi in your code at all. It's exactly the same as map, except for the index argument, but you're not using it, and your mapping is the identity function, so it's effectively a no-op. What's it about?

Resources