OCaml - How do I create a function with a function as output? - function

"Write a function lv: cfg -> (blabel -> ide set), which computes the live variables analysis on the given control flow graph."
Having cfg and blabel defined and ide set as a list of string, how can I create a function with that signature?

You're presumably familiar with the let syntax to define a function:
let f x = x + 1 in …
You can use this syntax anywhere, including in a function body. Now if you happen to use the inner function's name as the return value of the outer function, the outer function will be returning a function.
let outer_function x =
let inner_function y = x + y in
inner_function
The let syntax is in fact syntactic sugar for fun or function. In particular, if you define inner_function just to use the name once, you might as well use the fun notation and not bother giving the inner function a name.
let outer_function x =
fun y -> x + y
Furthermore, if all the outer function does when you pass it an argument is to build and return an inner function, then consider its behavior when you pass that function two arguments. First the outer function builds an inner function, using its first (and only) argument; then that inner function is applied to the second argument, so its body is executed. This is equivalent to having just one function that takes two arguments. This
observation is known as currying.
let outer_function x y = x + y
Note that the type of this function is int -> int -> int; this is the same type as int -> (int -> int) (the arrow type operator is right-associative).
Currying doesn't apply when the outer function does some work before building the inner function. In that case, the work is performed after receiving the first argument.
let outer_function x =
print_endline "outer";
fun y -> print_endline "inner"; x + y
So the structure of your code is likely to look like this:
let lv (c : cfg) : blabel -> ide set =
let c' = do_some_precomputation c in
fun (bl : blabel) -> (… : ide set)

Related

is there a way to return a fun that can have more than one arity?

Erlang functions can share the same name but have different arity. For example:
name(X) -> X.
name(X,Y) -> X * Y.
I would like to be able to return a fun from a function that behaves in the same way.
In this example I want a way to return fun/1 and fun/2 as one return, so the returned fun can be called in either way, exactly as the function example above.
function() ->
fun(X) -> X end,
fun(X,Y) -> X * Y end.
I could return a tuple {F1, F2} but that's ugly to use.
I could return a fun that takes a list as it's argument, but that's also rather ugly with calls like F([X]) or F([X, Y]).
Here you have 2 different functions with the same name:
name(X) -> X.
name(X,Y) -> X * Y.
These two functions, as anonymous functions, are: fun name/1 and fun name/2 respectively.
If you put any of them in a variable, say… F1 = fun name/1 or F2 = fun name/2, you will not be able to use those vars later interchangeably, since F1(1) will work, but F1(1,2) will fail (and viceversa with F2).
If you don't know the # of arguments you'll receive in runtime (let's say you receive a list of arguments of variable length), then you'll need to use erlang:apply/2 or erlang:apply/3 to dynamically evaluate the function. In that case, I can offer you 2 ways (depending on the version of erlang:apply that you prefer):
With apply/2:
use_name(Args) ->
Fun = function(length(Args)),
erlang:apply(Fun, Args).
function(1) -> fun(X) -> X end;
function(2) -> fun(X, Y) -> X * Y end.
With apply/3:
use_name(Args) ->
erlang:apply(?MODULE, name, Args).
name(X) -> X.
name(X,Y) -> X * Y.
Hope this helps.

F#: Apply a value as though it is a function

Is it possible in F# to apply a value as though it is a function? For example:
let record =
{|
Func = fun x -> x * x
Message = "hello"
|}
let message = record.Message // unsweetened field access
let unsweet = record.Func 3 // unsweetened function application
let sweet = record 3 // sweetened function application
Right now, the last line doesn't compile, of course:
error FS0003: This value is not a function and cannot be applied.
Is there some sort of syntactical sweetener that would allow me to "route" function application as I see fit, while still retaining its normal unsweetened behavior as well? I'm thinking of something magic like this:
// magically apply a record as though it was a function
let () record arg =
record.Func arg
(Note: I used a record in this example, but I'd be happy with a class as well.)
The closest thing I can think of would be a custom operator using statically resolved type parameters to resolve a specific property of type FSharpFunc, then invoke the function with the supplied input parameter. Something like this:
let record =
{|
Func = fun x -> x * x
Message = "hello"
|}
let inline (>.>) (r: ^a) v =
let f = (^a : (member Func: FSharpFunc< ^b, ^c>) r)
f v
record >.> 3 // val it : int = 9

difficult to understand function definition

cube (x,y,z) =
filter (pcubes x) cubes
cubes = [(a,b,c) | a <- [1..30],b <- [1..30],c <- [1..30]]
pcubes x (b,n,m) = (floor(sqrt(b*n)) == x)
so this code works, cubes makes a list of tuples,pcubes is used with filter to filter all the cubes in which floor(sqrt(b*n)) == x is satisfied,but the person who has modified my code wrote pcubes x in filter (pcubes x) cubes,how does this work.pcubes x makes a function that will initial the cubes x (b,n,m) that will take in a tuple and output a bool.the bool will be used in the filter function. How does this sort of manipulation happen? how does pcubes x access the (b,n,m) part of the function?
In Haskell, we don't usually use tuples (ie: (a,b,c)) to pass arguments to functions. We use currying.
Here's an example:
add a b = a + b
Here add is a function that takes a number, the returns another function that takes a number, then returns a number. We represent it's type as so:
add :: Int -> (Int -> Int)
Because of the way -> behaves, we can remove the parentheses in this case:
add :: Int -> Int -> Int
It is called like this:
(add 1) 2
but because of the way application works, we can just write:
add 1 2
Doesn't that look like our definition above, of the form add a b...?
Your function pcubes is similar. Here's how I'd write it:
pcubes x (b,n,m) = floor (sqrt (b*n)) == x
And as someone else said, it's type could be represented as:
pcubes :: Float -> (Float, Float, Float) -> Bool
When we write pcubes 1 the type becomes:
pcubes 1 :: (Float, Float, Float) -> Bool
Which, through currying, is legal, and can quite happily be used elsewhere.
I know, this is crazy black functional magic, as it was for me, but before long I guarantee you'll never want to go back: curried functions are useful.
A note on tuples: Expressions like (a,b,c) are data . They are not purely function-argument expressions. The fact that we can pull it into a function is called pattern matching, though it's not my turn to go into that.

Defining a function with a function as an argument

I am currently trying to define a function of type ('a -> 'a) -> 'a -> 'a which takes a function of type 'a -> 'a and an argument of type 'a and calls the function twice on the argument. I'm relatively new to OCaml but I do know how to define a function, but I had no luck with trial and error or Google trying to get a function to take a function as an argument and then apply that function twice.
Any tips or pointers would be greatly appreciated, thanks in advance.
edit: Thanks to Jeffrey below, my problem is now solved.
let f4 g a = g (g a );;
val f4 : ('a -> 'a) -> 'a -> 'a =
OCaml infers types, so if you use an argument as a function, it infers that it's a function. Here's an example:
# let f g = g 8 + g 10;;
val f : (int -> int) -> int = <fun>
# (~-);;
- : int -> int = <fun>
# f (~-);;
- : int = -18
To understand the example, note that (~-) is the ordinary integer negation operator.
Update: A hint for your more complicated problem. You need to test the value of n. Maybe an if statement would work? Second hint: if you use recursion, you don't need to use a loop. If you want to use a loop, don't use recursion. (Personally I'd suggest using recursion, it's like playing scales while learning piano.)

What does this function signature mean in sml?

I'm looking through some notes that my professor gave regarding the language SML and one of the functions looks like this:
fun max gt =
let fun lp curr [] = curr
| lp curr (a::l) = if gt(a,curr)
then lp a l
else lp curr l
in
lp
end
Could someone help explain what this is doing? The thing that I am most confused about is the line:
let fun lp curr [] = curr
What exactly does this mean? As far as I can tell there is a function called lp but what does the curr [] mean? Are these arguments? If so, aren't you only allowed one parameter in sml?
It means that lp is a function that takes 2 parameters, the first being curr and the second being, well, a list, which logically, may be either empty ([]) or contain at least one element ((a::l) is a pattern for a list where a is at the head, and the rest of the list is l).
If one were to translate that bit of FP code into a certain well-known imperative language, it would look like:
function lp(curr, lst) {
if (lst.length == 0) {
return curr;
} else {
var a = lst[0]; // first element
var l = lst.slice(1, lst.length); // the rest
if (gt(a, curr)) {
return lp(a, l);
} else {
return lp(curr, l)
}
}
}
Quite a mouthful, but it's a faithful translation.
Functional languages are based on the Lambda Calculus, where functions take exactly one value and return one result. While SML and other FP languages are based on this theory, it's rather inconvenient in practice, so many of these languages allow you to express passing multiple parameters to a function via what is known as Currying.
So yes, in ML functions actually take only one value, but currying lets you emulate multiple arguments.
Let's create a function called add, which adds 2 numbers:
fun add a b = a + b
should do it, but we defined 2 parameters. What's the type of add? If you take a look in the REPL, it is val add = fn : int -> int -> int. Which reads, "add is a function that takes an int and returns another function (which takes an int and returns an int)"
So we could also have defined add this way:
fun add a =
fn b => a + b
And you will see that they are alike. In fact it is safe to say that in a way,
the former is syntactic sugar for the later.
So all functions you define in ML, even those with several arguments, are actually functions with one argument, that return functions that accept the second argument and so on. It's a little hard to get used to at first but it
becomes second nature very soon.
fun add a b = a + b (* add is of type int -> int -> int *)
add 1 2 (* returns 3 as you expect *)
(* calling add with only one parameter *)
val add1 = add 1
What's add1? It is a function that will add 1 to the single argument you pass it!
add1 2 (* returns 3 *)
This is an example of partial application, where you are calling a function piecemeal,
one argument at a time, getting back each time, another function that accepts the rest
of the arguments.
Also, there's another way to give the appearance of multiple arguments: tuples:
(1, 2); (* evaluates to a tuple of (int,int) *)
fun add (a,b) = a + b;
add (1, 2) (* passing a SINGLE argument to a function that
expects only a single argument, a tuple of 2 numbers *)
In your question, lp could have also been implemented as lp (curr, someList):
fun max gt curr lst =
let fun lp (curr, []) = curr
| lp (curr, (a::l)) = if gt(a,curr) then lp (a, l)
else lp (curr, l)
in
lp (curr, lst)
end
Note that in this case, we have to declare max as max gt curr lst!
In the code you posted, lp was clearly implemented with currying. And the type of
max itself was fn: ('a * 'a -> bool) -> 'a -> 'a list -> 'a. Taking that apart:
('a * 'a -> bool) -> (* passed to 'max' as 'gt' *)
'a -> (* passed to 'lp' as 'curr' *)
'a list -> (* passed to 'lp' as 'someList' *)
'a (* what 'lp' returns (same as what 'max' itself returns) *)
Note the type of gt, the first argument to max: fn : (('a * 'a) -> bool) - it is a function of one argument ('a * 'a), a tuple of two 'a's and it returns an 'a. So no currying here.
Which to use is a matter of both taste, convention and practical considerations.
Hope this helps.
Just to clarify a bit on currying, from Faiz's excellent answer.
As previously stated SML only allows functions to take 1 argument. The reason for this is because a function fun foo x = x is actually a derived form of (syntactic sugar) val rec foo = fn x => x. Well actually this is not entirely true, but lets keep it simple for a second
Now take for example this power function. Here we declare the function to "take two arguments"
fun pow n 0 = 1
| pow n k = n * pow n (k-1)
As stated above, fun ... was a derived form and thus the equivalent form of the power function is
val rec pow = fn n => fn k => ...
As you might see here, we have a problem expressing the two different pattern matches of the original function declaration, and thus we can't keep it "simple" anymore and the real equivalent form of a fun declaration is
val rec pow = fn n => fn k =>
case (n, k) of
(n, 0) => 1
| (n, k) => n * pow n (k-1)
For the sake of completeness, cases is actually also a derived form, with anonymous functions as the equivalent form
val rec pow = fn n => fn k =>
(fn (n,0) => 1
| (n,k) => n * pow n (k-1)) (n,k)
Note that (n,k) is applied directly to the inner most anonymous function.