here is my code:
def f x
x
end
g = method(:f).to_proc.curry.(123)
p g
I want g to be a callable that takes no parameters and applies 123 to f. Instead, g contains the result of the application.
Am I doing it the complicated way?
EDIT: yes, g = lambda {f 123} works, but I am asking how to curry f.
The documentation for curry says that
If a sufficient number of arguments are supplied, it passes the supplied arguments to the original proc and returns the result.
So in this case you haven't really curried your function from a theoretical point of view, but practically you have. The
g = lambda {f 123}
seems to be closer to the spirit of returning a function that you can then call to evaluate, at least once all the arguments are determined.
Maybe you want to wrap your function f inside a lambda (evaluating f). Then you can curry the lambda expression, something like this:
g = lambda{f 123}.curry
p g[] // or g.call
Now g is callable that takes no parameters.
Related
Here is what I have and the error that I am getting sadly is
Error: This function has type 'a * 'a list -> 'a list
It is applied to too many arguments; maybe you forgot a `;'.
Why is that the case? I plan on passing two lists to the deleteDuplicates function, a sorted list, and an empty list, and expect the duplicates to be removed in the list r, which will be returned once the original list reaches [] condition.
will be back with updated code
let myfunc_caml_way arg0 arg1 = ...
rather than
let myfunc_java_way(arg0, arg1) = ...
Then you can call your function in this way:
myfunc_caml_way "10" 123
rather than
myfunc_java_way("10, 123)
I don't know how useful this might be, but here is some code that does what you want, written in a fairly standard OCaml style. Spend some time making sure you understand how and why it works. Maybe you should start with something simpler (eg how would you sum the elements of a list of integers ?). Actually, you should probably start with an OCaml tutorial, reading carefully and making sure you aunderstand the code examples.
let deleteDuplicates u =
(*
u : the sorted list
v : the result so far
last : the last element we read from u
*)
let rec aux u v last =
match u with
[] -> v
| x::xs when x = last -> aux xs v last
| x::xs -> aux u (x::v) x
in
(* the first element is a special case *)
match u with
[] -> []
| x::xs -> List.rev (aux xs [x] x)
This is not a direct answer to your question.
The standard way of defining an "n-ary" function is
let myfunc_caml_way arg0 arg1 = ...
rather than
let myfunc_java_way(arg0, arg1) = ...
Then you can call your function in this way:
myfunc_caml_way "10" 123
rather than
myfunc_java_way("10, 123)
See examples here:
https://github.com/ocaml/ocaml/blob/trunk/stdlib/complex.ml
By switching from myfunc_java_way to myfunc_caml_way, you will be benefited from what's called "Currying"
What is 'Currying'?
However please note that you sometimes need to enclose the whole invocation by parenthesis
myfunc_caml_way (otherfunc_caml_way "foo" "bar") 123
in order to tell the compiler not to interpret your code as
((myfunc_caml_way otherfunc_caml_way "foo") "bar" 123)
You seem to be thinking that OCaml uses tuples (a, b) to indicate arguments of function calls. This isn't the case. Whenever some expressions stand next to each other, that's a function call. The first expression is the function, and the rest of the expressions are the arguments to the function.
So, these two lines:
append(first,r)
deleteDuplicates(remaining, r)
Represent a function call with three arguments. The function is append. The first argument is (first ,r). The second argument is deleteDuplicates. The third argument is (remaining, r).
Since append has just one argument (a tuple), you're passing it too many arguments. This is what the compiler is telling you.
You also seem to be thinking that append(first, r) will change the value of r. This is not the case. Variables in OCaml are immutable. You can't do anything that will change the value of r.
Update
I think you have too many questions for SO to help you effectively at this point. You might try reading some OCaml tutorials. It will be much faster than asking a question here for every error you see :-)
Nonetheless, here's what "match failure" means. It means that somewhere you have a match that you're applying to an expression, but none of the patterns of the match matches the expression. Your deleteDuplicates code clearly has a pattern coverage error; i.e., it has a pattern that doesn't cover all cases. Your first match only works for empty lists or for lists of 2 or more elements. It doesn't work for lists of 1 element.
I want the common name of a higher order function that applies a list of functions onto a single argument.
In this sense it is a converse of map. map takes a function and a list of arguments and applies that function to the entire list. In Python it might look like this
map = lambda fn, args: [fn(arg) for arg in args]
I'm thinking of the function that does the same but has the alternate argument as a list type
??? = lambda fns, arg: [fn(arg) for fn in fns]
I suspect that this function exists and has a common name. What is it?
Actually, what you describe is not the converse of map, but just map applied in another way. Consider, e.g.,
map(lambda f: f(2), [lambda x: x + 1, lambda x: x, lambda x: x * x])
which in effect applies three functions (plus 1, identity, and squaring) to the argument 2. So what you wanted is just
alt_map = lambda x, fns: map(lambda f: f(x), fns)
which is still an ordinary map.
Consider splatter in this Python code:
def splatter(fn):
return lambda (args): fn(*args)
def add(a, b):
return a + b
list1 = [1, 2, 3]
list2 = [4, 5, 6]
print map(splatter(add), zip(list1, list2))
Mapping an n-ary function over n zipped sequences seems like a common enough operation that there might be a name for this already, but I have no idea where I'd find that. It vaguely evokes currying, and it seems like there are probably other related argument-centric HOFs that I've never heard of. Does anyone know if this is a "well-known" function? When discussing it I am currently stuck with the type of awkward language used in the question title.
Edit
Wow, Python's map does this automatically. You can write:
map(add, list1, list2)
And it will do the right thing, saving you the trouble of splattering your function. The only difference is that zip returns a list whose length is the the length of its shortest argument, whereas map extends shorter lists with None.
I think zipWith is the function that you are searching (this name is at least used in Haskell). It is even a bit more general. In Haskell zipWith is defined as follows (where the first line is just the type):
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
zipWith _ _ _ = []
And your example would be something like
zipWith (+) [1, 2, 3] [4, 5, 6]
Since I do not know python very well I can only point to "zipWith analogue in Python?".
I randomly saw this in my list of "Questions asked," and was surprised that I now know the answer.
There are two interpretations of the function that I asked.
The first was my intent: to take a function that takes a fixed number of arguments and convert it into a function that takes those arguments as a fixed-size list or tuple. In Haskell, the function that does this operation is called uncurry.
uncurry :: (a -> b -> c) -> ((a, b) -> c)
(Extra parens for clarity.)
It's easy to imagine extending this to functions of more than two arguments, though it can't be expressed in Haskell. But uncurry3, uncurry4, etc. would not be out of place.
So I was right that it "vaguely evokes currying," as it is really the opposite.
The second interpretation is to take a function that takes an intentionally variable number of arguments and return a function that takes a single list.
Because splat is so weird as a syntactic construct in Python, this is hard to reason about.
But if we imagine, say, JavaScript, which has a first-class named function for "splatting:"
varFn.apply(null, args)
var splatter = function(f) {
return function(arg) {
return f.apply(null, arg);
};
};
Then we could rephrase that as merely a partial application of the "apply" function:
var splatter = function(f) {
return Function.prototype.apply.bind(f, null);
};
Or using, Underscore's partial, we can come up with the point-free definition:
var splatter = _.partial(Function.prototype.bind.bind(Function.prototype.apply), _, null)
Yes, that is a nightmare.
(The alternative to _.partial requires defining some sort of swap helper and would come out even less readable, I think.)
So I think that the name of this operation is just "a partial application of apply", or in the Python case it's almost like a section of the splat operator -- if splat were an "actual" operator.
But the particular combination of uncurry, zip, and map in the original question is exactly zipWith, as chris pointed out. In fact, HLint by default includes a rule to replace this complex construct with a single call to zipWith.
I hope that clears things up, past Ian.
I use the LINQ Aggregate operator quite often. Essentially, it lets you "accumulate" a function over a sequence by repeatedly applying the function on the last computed value of the function and the next element of the sequence.
For example:
int[] numbers = ...
int result = numbers.Aggregate(0, (result, next) => result + next * next);
will compute the sum of the squares of the elements of an array.
After some googling, I discovered that the general term for this in functional programming is "fold". This got me curious about functions that could be written as folds. In other words, the f in f = fold op.
I think that a function that can be computed with this operator only needs to satisfy (please correct me if I am wrong):
f(x1, x2, ..., xn) = f(f(x1, x2, ..., xn-1), xn)
This property seems common enough to deserve a special name. Is there one?
An Iterated binary operation may be what you are looking for.
You would also need to add some stopping conditions like
f(x) = something
f(x1,x2) = something2
They define a binary operation f and another function F in the link I provided to handle what happens when you get down to f(x1,x2).
To clarify the question: 'sum of squares' is a special function because it has the property that it can be expressed in terms of the fold functional plus a lambda, ie
sumSq = fold ((result, next) => result + next * next) 0
Which functions f have this property, where dom f = { A tuples }, ran f :: B?
Clearly, due to the mechanics of fold, the statement that f is foldable is the assertion that there exists an h :: A * B -> B such that for any n > 0, x1, ..., xn in A, f ((x1,...xn)) = h (xn, f ((x1,...,xn-1))).
The assertion that the h exists says almost the same thing as your condition that
f((x1, x2, ..., xn)) = f((f((x1, x2, ..., xn-1)), xn)) (*)
so you were very nearly correct; the difference is that you are requiring A=B which is a bit more restrictive than being a general fold-expressible function. More problematically though, fold in general also takes a starting value a, which is set to a = f nil. The main reason your formulation (*) is wrong is that it assumes that h is whatever f does on pair lists, but that is only true when h(x, a) = a. That is, in your example of sum of squares, the starting value you gave to Accumulate was 0, which is a does-nothing when you add it, but there are fold-expressible functions where the starting value does something, in which case we have a fold-expressible function which does not satisfy (*).
For example, take this fold-expressible function lengthPlusOne:
lengthPlusOne = fold ((result, next) => result + 1) 1
f (1) = 2, but f(f(), 1) = f(1, 1) = 3.
Finally, let's give an example of a functions on lists not expressible in terms of fold. Suppose we had a black box function and tested it on these inputs:
f (1) = 1
f (1, 1) = 1 (1)
f (2, 1) = 1
f (1, 2, 1) = 2 (2)
Such a function on tuples (=finite lists) obviously exists (we can just define it to have those outputs above and be zero on any other lists). Yet, it is not foldable because (1) implies h(1,1)=1, while (2) implies h(1,1)=2.
I don't know if there is other terminology than just saying 'a function expressible as a fold'. Perhaps a (left/right) context-free list function would be a good way of describing it?
In functional programming, fold is used to aggregate results on collections like list, array, sequence... Your formulation of fold is incorrect, which leads to confusion. A correct formulation could be:
fold f e [x1, x2, x3,..., xn] = f((...f(f(f(e, x1),x2),x3)...), xn)
The requirement for f is actually very loose. Lets say the type of elements is T and type of e is U. So function f indeed takes two arguments, the first one of type U and the second one of type T, and returns a value of type U (because this value will be supplied as the first argument of function f again). In short, we have an "accumulate" function with a signature f: U * T -> U. Due to this reason, I don't think there is a formal term for these kinds of function.
In your example, e = 0, T = int, U = int and your lambda function (result, next) => result + next * next has a signaturef: int * int -> int, which satisfies the condition of "foldable" functions.
In case you want to know, another variant of fold is foldBack, which accumulates results with the reverse order from xn to x1:
foldBack f [x1, x2,..., xn] e = f(x1,f(x2,...,f(n,e)...))
There are interesting cases with commutative functions, which satisfy f(x, y) = f(x, y), when fold and foldBack return the same result. About fold itself, it is a specific instance of catamorphism in category theory. You can read more about catamorphism here.
val y=2;
fun f(x) = x*y;
fun g(h) = let val y=5 in 3+h(y) end;
let val y=3 in g(f) end;
I'm looking for a line by line explanation. I'm new to ML and trying to decipher some online code. Also, a description of the "let/in" commands would be very helpful.
I'm more familiar with ocaml but it all looks the same to me.
val y=2;
fun f(x) = x*y;
The first two lines bind variables y and f. y to an integer 2 and f to a function which takes an integer x and multiplies it by what's bound to y, 2. So you can think of the function f takes some integer and multiplies it by 2. (f(x) = x*2)
fun g(h) = let val y=5
in
3+h(y)
end;
The next line defines a function g which takes some h (which turns out to be a function which takes an integer and returns an integer) and does the following:
Binds the integer 5 to a temporary variable y.
You can think of the let/in/end syntax as a way to declare a temporary variable which could be used in the expression following in. end just ends the expression. (this is in contrast to ocaml where end is omitted)
Returns the sum of 3 plus the function h applying the argument y, or 5.
At a high level, the function g takes some function, applies 5 to that function and adds 3 to the result. (g(h) = 3+h(5))
At this point, three variables are bound in the environment: y = 2, f = function and g = function.
let val y=3
in
g(f)
end;
Now 3 is bound to a temporary variable y and calls function g with the function f as the argument. You need to remember that when a function is defined, it keeps it's environment along with it so the temporary binding of y here has no affect on the functions g and f. Their behavior does not change.
g (g(h) = 3+h(5)), is called with argument f (f(x) = x*2). Performing the substitutions for parameter h, g becomes 3+((5)*2) which evaluates to 13.
I hope this is clear to you.