Problem:Define the function mapf whose first argument is a unary function, and second argument list. The result is a list of the function applied to each element of the argument list. Write a one-liner using fold_right, and not a recursive function.
Solution:
let mapf fn list = fold_right (fun h t -> fn h :: t) list []
I don't understand how that solves the problem because fold_right computes a function with the list arguments in a recursive way, so it returns a value and not a list. I neither understand what the following notation means:
fun h t -> fn h :: t
Your two questions are related. It's true that fold_right returns a value, but a list is a value!
The :: operator adds a new element to the beginning of a list. So the value computed by this application of fold_right is indeed a list.
Another way to think of this might be as follows. If you use fold_right with the + operator you compute a value like so:
fold_right (+) [1; 2; 3] 0 =>
1 + 2 + 3 + 0 =>
6
If you use fold_right with the :: operator, you compute a value like so:
fold_right (::) [1; 2; 3] [] =>
1 :: 2 :: 3 :: [] =>
[1; 2; 3]
This isn't theoretical, it works exactly like this in the REPL:
# List.fold_right (+) [1; 2; 3] 0;;
- : int = 6
# List.fold_right (fun a b -> a :: b) [1; 2; 3] [];;
- : int list = [1; 2; 3]
(You need to write fun a b -> a :: b because the :: notation can't actuallly be used as a stand-alone function. Unfortunately.)
Note that it's completely legitimate to write a list using the :: operator yourself:
# 1 :: 2 :: 3 :: [];;
- : int list = [1; 2; 3]
Update
First, fun x y -> expr is the notation for a "lambda" in OCaml, i.e., for a function literal.
The function fun h t -> fn h :: t takes two values h and t. It applies the function fn to h, and returns a new list with this new value at the front of t.
From a typing standpoint, the value h must be the right type to pass to fn, and fn must return a value of the right type to be in the list t.
You could parenthesize it like this: fun h t -> (fn h) :: t, if that makes it clearer.
The function fun a b -> a :: b is similar except that it just puts a directly onto the list b. It doesn't apply any function. In essence, it does just what the :: operator does.
From a typing standpoint, a has to be the right type to be an element of the list b.
Update 2
If you're trying to understand what a lambda is, one way of looking at it is that it's just a handy way to write a function that's reasonably small. You can easily write your given code without the lambda:
let mapf fn list =
let helper h t = fn h :: t in
List.fold_right helper list []
Instead of a lambda, this version has a locally declared function named helper.
Another way of looking at it is that all functions are lambdas. The idiomatic way of writing a function:
let f x y = x + y
is just a handy abbreviation for a version with an explicit lambda:
let f = fun x y -> x + y
So, really, a lambda isn't a special kind of function. It's exactly like any other function. It's just a notational choice.
Related
I referenced codes in this question: How to implement a dictionary as a function in OCaml?, and I wrote my code of functional dictionary in OCaml:
type key = string;;
type 'a dict = key -> 'a option;;
let add (d : 'a dict) (k, v) : 'a dict = fun k' -> if k' = k then v else d k';;
let empty () = ... ;;
let find d k = ... ;;
In this code, what I want to know is how the add function works. What does the variable k' mean? When we use fun keyword, for example, let sub x = fun y -> x - y;;, the variable that comes next to the fun means an argument. Is it right? When I want to use the sub function I defined, we can call the function with
# sub 1 2;;
- : int = -1
and 2 is an argument that is bound to y, which is the variable next to the fun keyword. However, in the dictionary code above, there is the variable k' in the add function, next to the fun keyword, but it does not represent any additional argument. Arguments that are needed to call the add function is a 'a dict type variable and a (k, v) type tuple. No third argument is required. Then, what does the k' mean? I have no idea.
In OCaml,
let sub x y = x - y
is a shorthand notation (the syntactic sugar) for
let sub = fun x -> fun y -> x - y
To get it, let's pick an even simpler example,
let succ x = x + 1
is the shorter syntactic form for
let succ = fun x -> x + 1
which says that we bind the name succ to a function fun x -> x + 1, where the latter is the function literal. A literal in programming languages is the syntactic notation for defining values. For example, for integers we have a finite set of literals 1, 2, 3, etc. For strings, we have a practically infinite set of literals, e.g., "hello", "", "etc". A function in OCaml is also a value, the same as an integer or a string, therefore it has a syntax for function literals, which is
fun <arg> -> <body>
It creates a function, that evaluates to the value of <body> in which all free occurrences of <arg> are substituted be the actually passed parameter.
As you probably noticed, we could really bind only one parameter in the function literal. Indeed, all functions in OCaml are unary. You may already know that you can define functions like fun x y -> x - y, but this is also just syntactic sugar for fun x -> fun y -> x - y. So what the latter notation means? Let's ascribe parenthesis to get the idea of how this function is evaluated:
fun x -> (fun y -> x - y)
So we can recognize the fun x -> <body> part, where <body> is a function on itself, i.e., <body> = fun y -> x - y. That means that expression fun x -> fun y -> x - y is a function, that takes an argument x and returns another function, that takes an argument y and returns x-y. This way of defining functions, i.e., when instead of having functions that accept tuples you have a function that returns a function and so on, is called currying.
Now, when we are comfortable with the idea of currying and that all functions in OCaml are really of one argument, we can go back to the original example of the functional dictionaries.
The add function
let add (d : 'a dict) (k, v) : 'a dict = fun k' -> if k' = k then v else d k'
stripped of the (unnecessary) type annotations
let add d (k, v) = fun k' -> if k' = k then v else d k'
and then represented in the form that makes currying explicit, is
let add = fun d -> fun (k, v) -> fun k' -> if k' = k then v else d k'
So it is a function that for given dictionary d produces a function that takes a pair (k,v) and returns a function that for all k' that are equal to k will return d. And if keys are different, then it applies the key to the first parameter d. Let's take a deeper look at the
fun k' -> if k' = k then v else d k'
literal. As we can see variables d and k occur free in that function, i.e., they are not bound by the parameter k. When a function references a variable from the outer scope (which is not defined on the module level), a closure is created. A closure is an opaque object that contains a pointer to the code1 (in our case it is if k' = k then v else d k' and pointers to each captured variable (i.e., to each variable that is taken from the outer scope). In our case, it creates (roughly) a record that has three entries, d, k and the code. After a few hours of mediation, it is not hard to see, that a function dictionary is just singly-linked list of closures, as d is a pointer to the closure, which, in turn, contains a pointer to another closure, until we reach the pointer to empty, which returns None no matter the key (and is coded incorrectly in your example, as it should expect any key, not for the value of type unit).
With all that said and kept in mind, we can now write the short-hand notation for the add function:
let add d k k' = if k' = k then v else d k'
which has absolutely the same semantics (i.e., meaning, behavior) as any other notations, as it is just the syntactic sugar.
1)To prevent any confusion, the code itself is never stored in the heap memory. Even when you have an anonymous function that is not bound to any name, e.g., (fun x y -> x + y) 2 3 the compiler will emit the code and store it in the text section of a binary and give it some funny name. So the code above will be just a normal call to a function with mangled name, e.g., call Testing_fun001. And going back to the functional dictionary example, each entry will be an object with three words, the key, the data, the pointer to the next entry. Basically the same underlying representation as an association list.
About your type definitions..
type key = string;;
type 'a dict = key -> 'a option;;
Why not...
type 'a dict = 'a -> 'a option;;
Or even better...
type ('a, 'b) dict = 'a -> 'b option;;
I would like to iterate over all combinations of elements from a list of lists which have the same length but not necessarily the same type. This is like the cartesian product of two lists (which is easy to do in OCaml), but for an arbitrary number of lists.
First I tried to write a general cartesian (outer) product function which takes a list of lists and returns a list of tuples, but that can't work because the input list of lists would not have elements of the same type.
Now I'm down to a function of the type
'a list * 'b list * 'c list -> ('a * 'b * 'c) list
which unfortunately fixes the number of inputs to three (for example). It's
let outer3 (l1, l2, l3) =
let open List in
l1 |> map (fun e1 ->
l2 |> map (fun e2 ->
l3 |> map (fun e3 ->
(e1,e2,e3))))
|> concat |> concat
This works but it's cumbersome since it has to be redone for each number of inputs. Is there a better way to do this?
Background: I want to feed the resulting flat list to Parmap.pariter.
To solve your task for arbitrary ntuple we need to use existential types. We can use GADT, but they are close by default. Of course we can use open variants, but I prefer a little more syntactically heavy but more portable solution with first class modules (and it works because GADT can be expressed via first class modules). But enough theory, first of all we need a function that will produce the n_cartesian_product for us, with type 'a list list -> 'a list list
let rec n_cartesian_product = function
| [] -> [[]]
| x :: xs ->
let rest = n_cartesian_product xs in
List.concat (List.map (fun i -> List.map (fun rs -> i :: rs) rest) x)
Now we need to fit different types into one type 'a, and here comes existential types, let's define a signature:
module type T = sig
type t
val x : t
end
Now let's try to write a lifter to this existential:
let int x = (module struct type t = int let x = x end : T)
it has type:
int -> (module T)
Let's extend the example with few more cases:
let string x = (module struct type t = string let x = x end : T)
let char x = (module struct type t = char let x = x end : T)
let xxs = [
List.map int [1;2;3;4];
List.map string ["1"; "2"; "3"; "4"];
List.map char ['1'; '2'; '3'; '4']
]
# n_cartesian_product xxs;;
- : (module T) list list =
[[<module>; <module>; <module>]; [<module>; <module>; <module>];
[<module>; <module>; <module>]; [<module>; <module>; <module>];
...
Instead of first class modules you can use other abstractions, like objects or functions, if your type requirements allow this (e.g., if you do not need to expose the type t). Of course, our existential is very terse, and maybe you will need to extend the signature.
I used #ivg 's answer but in a version with a GADT. I reproduce it here for reference. In a simple case where only the types float and int can appear in the input lists, first set
type wrapped = Int : int -> wrapped | Float : float -> wrapped
this is a GADT without type parameter. Then
let wrap_f f = Float f
let wrap_i i = Int f
wrap types into the sum type. On wrapped value lists we can call n_cartesian_product from #ivg 's answer. The result is a list combinations: wrapped list list which is flat (for the present purposes).
Now to use Parmap, i have e.g. a worker function work : float * int * float * float -> float. To get the arguments out of the wrappers, I pattern match:
combinations |> List.map (function
| [Float f1; Int i; Float f2; Float f3] -> (f1, i, f2, f3)
| _ -> raise Invalid_argument "wrong parameter number or types")
to construct the flat list of tuples. This can be finally fed to Parmap.pariter with the worker function work.
This setup is almost the same as using a regular sum type type wrapsum = F of float | I of int instead of wrapped. The pattern matching would be the same; the only difference seems to be that getting a wrong input, e.g. (F 1, I 1, F 2.0, F, 3.0) would be detected only at runtime, not compile time as here.
I'm having trouble using list pattern with multiple parameters. For example, trying to define:
somefunction (x:xs) (y:ys) = x:[y]
results in Occurs check: cannot construct the infinite type: t0 = [t0].
Basically, I want to take two lists as parameters to a function and manipulate each of them using the (x:xs) pattern matching approach. Why is this wrong and how can I do it right? Thank you much!
EDIT: Update with more code as suggested was needed in answers.
somefunction a [] = [a]:[]
somefunction [] b = [b]:[]
somefunction (x:xs) (y:ys) = x:[y]
EDIT 2: Missed an important update. The error I'm getting with the above code is Occurs check: cannot construct the infinite type: t0 = [[t0]]. I think I understand the problem now.
Your function snippet is perfectly sound:
(! 514)-> ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> let f (x:xs) (y:ys) = x:[y]
Prelude> :type f
f :: [a] -> [a] -> [a]
But the context contradicts that type, and the type inference give you that error. For instance, I can create a context that will give this error:
Prelude> let g xs ys = xs : ys
Prelude> :type g
g :: a -> [a] -> [a]
And then if I combine f and g like below, then I get your error:
Prelude> let z x y = g x (f x y)
<interactive>:7:20:
Occurs check: cannot construct the infinite type: a0 = [a0]
In the first argument of `f', namely `x'
In the second argument of `g', namely `(f x y)'
In the expression: g x (f x y)
Prelude>
To understand you error properly, you will need to examine (or post) enough context.
The problem is with all 3 lines taken together:
somefunction a [] = [a]:[]
somefunction [] b = [b]:[]
somefunction (x:xs) (y:ys) = x:[y]
None of them are incorrect taken on their own. The problem is that the three equations are inconsistent about the return type of somefunction.
From the last equation, we can see that both arguments are lists (since you pattern match on them using the list constructor :).
From the last equation, we can see that the return type is a list whose elements must be the same type as the elements of the argument lists (which must also both be the same type), since the return value is x:[y] (which is more often written [x, y]; just the list containing only the two elements x and y) and x and y were elements of the argument lists. So if x has type t0, the arguments to somefunction both have type [t0] and the return type is [t0].
Now try to apply those facts to the first equation. a must be a list. So [a] (the list containing exactly one element a) must be a list of lists. And then [a]:[] (the list whose first element is [a] and whose tail is empty - also written [[a]]) must be a list of lists of lists! If the parameter a has type [t0] (to match the type we figured out from looking at the last equation), then [a] has type [[t0]] and [a]:[] (or [[a]]) has type [[[t0]]], which is the return type we get from this equation.
To reconcile what we learned from those two equations we need to find some type expression to use for t0 such that [t0] = [[[t0]]], which also requires that t0 = [[t0]]. This is impossible, which is what the error message Occurs check: cannot construct the infinite type: t0 = [[t0]] was about.
If your intention was to return one of the parameters as-is when the other one is empty, then you need something more like:
somefunction a [] = a
somefunction [] b = b
somefunction (x:xs) (y:ys) = [x, y]
Or it's possible that the first two equations were correct (you intend to return a list of lists of lists?), in which case the last one needs to be modified. Without knowing what you wanted the function to do, I can't say.
May be you want to write:
somefunction xs [] = xs
somefunction [] ys = ys
somefunction (x:xs) (y:ys) = x : y : []
You have extra brackets. And your definition of x : y not contains []. So compiler think, y is already a list
I need to find a way to combine two functions and output them as one.
I have the following code where take in a list of function ('a->'a) list then output a function ('a->'a) using the List.fold_left.
I figured out the base case, but I tried a lot of ways to combine two functions. The output should have the type ('a -> 'a) list -> ('a -> 'a).
example output:
# pipe [] 3;;
- : int = 3
# pipe [(fun x-> 2*x);(fun x -> x + 3)] 3 ;;
- : int = 9
# pipe [(fun x -> x + 3);(fun x-> 2*x)] 3;;
- : int = 12
function:
let p l =
let f acc x = fun y-> fun x->acc in (* acc & x are functions 'a->'a *)
let base = fun x->x in
List.fold_left f base l
Since you know that you have to use a left fold, you now have to solve a fairly constrained problem: given two functions of type 'a -> 'a, how do you combine them into a single function of the same type?
In practice, there is one general way of combining functions: composition. In math, this is usually written as f ∘ g where f and g are the functions. This operation produces a new function which corresponds to taking an argument, applying g to it and then applying f to the result. So if h = f ∘ g, then we can also write this as h(x) = f(g(x)).
So your function f is actually function composition. (You should really give it a better name than f.) It has to take in two functions of type 'a -> 'a and produce another function of the same type. This means it produces a function of one argument where you produce a function taking two arguments.
So you need to write a function compose (a more readable name than f) of type ('a -> 'a) -> ('a -> 'a) -> ('a -> 'a). It has to take two arguments f and g and produce a function that applies both of them to its argument.
I hope this clarifies what you need to do. Figuring out exactly how to do it in OCaml is a healthy exercise.
For instance, i have a list like ['a','b','c','d','e'].
I want to do something like this:
First do something with the first two elements, f 'a' 'b'
Then do the same thing with the return value of f and next element in the list, result = f 'a' 'b', lets say like f result 'c'. Then f resultof(result 'c') 'd' and so on.
How can i do something like this?
First let's consider that function f that you have. It takes some sort of accumulated value, a plain value, and combines them into a result. So, in the type signature, we'll say a for the type of the accumulated value, v for the type of the value, and r for the type of the result.
f :: a -> v -> r
Now we want to create a folding function that uses f and a list of values.
someFold :: (a -> v -> r) -> [v] -> ?
What should it return? It should yield something of the resultant type r, right? Notice now that a and r should actually be the same type, since we keep feeding the result of f into it's first argument again.
someFold :: (a -> v -> a) -> [v] -> a
Now one thing's missing. How do you get the very first a? There are two ways to look at that. Either you just pick the first value, in which case a is the same type as v, or you specify a base value, so a could actually be different than v. Let's go with the latter, since that's more interesting. Let's also decide to move left to right in this list. (That's what you need, right?)
someFold :: (a -> v -> a) -> a -> [v] -> a
So...how do we implement it? It'll be recursive, so let's start with the base cases.
someFold f acc [] = acc
If we hit the end of the list, then we've accumulated enough, right? That was easy. So how about the recursive case? From what you said, at each step we should apply f to the "accumulated value so far" as the first argument, and the "first value of the list" as the second. f acc x. Then we keep folding, using that as our new "accumulated" value.
someFold f acc (x:xs) = someFold f (f acc x) xs
Easy, right? But...what if we want to do like you said and start the function by taking the first two values of the list? Also easy. Just take the first element, and call it the original "base" accumulator!
someFold1 :: (v -> v -> v) -> [v] -> v
someFold1 f (x:xs) = someFold f x xs
Notice that since a is the same type as v for this special case, the function someFold1 has a very amusing type signature. If you understood this explanation, then congrats. We've just implemented foldl and foldl1.
Prelude> foldl1 min "abcde" -- "abcde" is sugar for ['a','b','c','d','e']
'a'
In real code, you should actually use foldl' and friends.
Sounds like homework. Take a look at folds.
In this case, the problem with a fold is, that it usually processes on element at a time. You could try to manually roll a fold.
Assume, you have your function f, that gets two elements at a time and the accumulator (the result of the last iteration) fed. Then you function looks like this:
fold2 :: (a -> a -> b -> b) -> [a] -> b -> b
fold2 f accum (x:y:zs) = fold2 f (f x y) zs
fold2 _ accum [] = accum
fold2 _ _ _ = error "odd number of elements"
Try to understand this. fold2 shaves the top two elements of the list of and feeds it into f. The result this is then passed as the new accumulator to the recursive call. This is done until the list is empty.