https://ocaml.org/learn/tutorials/99problems.html
I am trying to understand the solution for generating the combinations of K distinct objects chosen from the N elements of a list. Here are the code:
let extract k list =
let rec aux k acc emit = function
| [] -> acc
| h :: t ->
if k = 1 then aux k (emit [h] acc) emit t else
let new_emit x = emit (h :: x) in
aux k (aux (k-1) acc new_emit t) emit t
in
let emit x acc = x :: acc in
aux k [] emit list;;
The emit function is defined to accept two parameters:
let emit x acc = x :: acc
So I don't quite understand how the following line works since it call emit giving only a single argument:
let new_emit x = emit (h :: x)
Also, the new_emit function accept only a single parameter and is passed as an argument to the aux function, how can it deal with the following line (the emit here is called by giving two arguments):
if k = 1 then aux k (emit [h] acc) emit t
Functions in OCaml are usually curried, meaning that multiple argument functions are expressed by taking one argument and returning a function that takes the next argument (and so on). OCaml has some syntax sugar to make this nicer to read: let f x y = ... is short for let f = fun x -> fun y -> ....
Usually programmers use such functions by passing all the arguments at once, but it is possible to only pass one and get back a 'partially applied' function as a result. That is what is happening with emit.
So you can read let emit_new x = emit (h :: x) as defining a version of emit with the first argument already supplied.
The point that you are missing here is that due to currying and first-class functions, the number of parameters of a function is not as rigid as you think it is.
In this particular case, the definition of emit as
let emit x acc = x :: acc
gives it the type 'a -> 'a list -> 'a list. This type can have two different readings, you can either think of it as a function that takes two argument, one of type 'a and one of type 'a list and returns an object of type 'a list. But, you can also read it as function that takes one argument of type 'a and returns a function of type 'a list -> 'a list.
The definition
let new_emit x = emit (h :: x)
is using this curried interpretation: since emit has for type
'a -> 'a list -> 'a list, applying it to h::x yields a function of type
'a list -> 'a list, consequently the function new_emit has for type
'a -> 'a list -> 'a list. In other words, the function new_emit still accepts two input parameters, even if it definitions only involve one argument. Note, to make things easier to understand the definition of new_emit can also be written either
let new_emit x = fun acc -> emit (h :: x) acc
or
let new_emit x acc = emit (h :: x) acc
In context, the emit element_list combination_list is used to add a new combination to the list of combinations by taking the element_list and adding to it all previously picked elements. The definition of new_emit is then used to pick the new element h. In other words, this line
if k = 1 then aux k (emit [h] acc) emit t else
means add the element list [h] plus all previously picked elements to the combination list since all elements have been picked, whereas
let new_emit x = emit (h :: x) in
aux k (aux (k-1) acc new_emit t) emit t
could be decomposed as:
First pick the element h:
let new_emit x = emit (h :: x)
then construct all combinations where h is present:
let combination_where_h_was_selected = aux (k-1) acc new_emit t
and then construct all combination where h is absent:
aux k combination_where_h_was_selected emit t
p.s.:
As a far more advanced remarks on the subject of the numbers of parameters of a function, note that even "variadic" function are perfectly possibly in OCaml. For instance, an abstruse and inefficient way to define list would be
let start f = f (fun x -> x)
let elt x t k = k (fun l -> t (fun l -> x ::l) l)
let stop f = f (fun x -> x) []
let [] = start stop
let l = start (elt 1) (elt 2) (elt 3) (elt 4) stop
;; assert ( l = [1;2;3;4] )
Related
I'm learning Haskell and have some problems with list comprehension.
If I define a function to get a list of the divisors of a given number, I get an error.
check n = [x | x <- [1..(floor (n/2))], mod n x == 0]
I don't get why it's causing an error. If I want to generate a list from 1 to n/2 I can do it with [1..(floor (n/2))], but not if I do it in the list comprehension.
I tried another way but I get also an error (in this code I want to get all so called "perfect numbers")
f n = [1..(floor (n/2))]
main = print $ filter (\t -> foldr (+) 0 (f t) == t) [2..100]
Usually it is better to start writing a signature. While signatures are often not required, it makes it easier to debug a single function.
The signature of your check function is:
check :: (RealFrac a, Integral a) => a -> [a]
The type of input (and output) a thus needs to be both a RealFrac and an Integral. While technically speaking we can make such type, it does not make much sense.
The reason this happens is because of the use of mod :: Integral a => a -> a -> a this requires x and n to be both of the same type, and a should be a member of the Integral typeclass.
Another problem is the use of n/2, since (/) :: Fractional a => a -> a -> a requires that n and 2 have the same type as n / 2, and n should also be of a type that is a member of Fractional. To make matters even worse, we use floor :: (RealFrac a, Integral b) => a -> b which enforces that n (and thus x as well) have a type that is a member of the RealFrac typeclass.
We can prevent the Fractional and RealFrac type constaints by making use of div :: Integral a => a -> a -> a instead. Since mod already required n to have a type that is a member of the Integral typeclass, this thus will not restrict the types further:
check n = [x | x <- [1 .. div n 2], mod n x == 0]
This for example prints:
Prelude> print (check 5)
[1]
Prelude> print (check 17)
[1]
Prelude> print (check 18)
[1,2,3,6,9]
Do you have any idea how I can loop the function func2 10 times
type Vertex = Int
type OutNeighbors = [Vertex]
data Graph = Graph [(Vertex,OutNeighbors)] deriving (Eq, Show, Read)
func2 (Graph g) = filter (\x -> contains (fst x) (func1 (Graph g))) g --I need to repeat this function 10 times.
I am kind of new to haskell and I have no idea how to do loops
Do you have any idea how I can loop the function func2 10 times
You could iterate it and !! at 10:
> take 5 $ iterate ("hi " ++) "there!"
["there!","hi there!","hi hi there!","hi hi hi there!","hi hi hi hi there!"]
> let func2 = (+3) in iterate func2 0 !! 10
30
but that would require func2 to return the same type as its input, and right now it appears to have type
func2 :: Graph -> [(Vertex,OutNeighbors)]
But if you wrapped Graph back onto it, i.e.,
func2 :: Graph -> Graph
func2 (Graph g) = Graph (... g)
then you could iterate on it.
In Haskell you can use recursion for loops, here is an example:
myLoop 0 g = g
myLoop n g = myLoop (n - 1) (Graph (func2 g))
Now calling myLoop 10 g will call func2 10 times on g.
Note that I had to wrap the result back in the Graph type, that is probably something you should do in the func2 function:
func2 (Graph g) = Graph (filter (\x -> contains (fst x) (func1 (Graph g))) g)
You can get a little bit higher-level if you wrap this up in the State monad from the transformers package:
import Control.Monad.Trans.State.Lazy (execState, modify)
import Control.Monad (replicateM_)
myLoop :: Int -> Graph -> Graph
myLoop n g = execState (replicateM_ n (modify func2)) g
This is one of these situations where, in order to avoid typing errors, you need to be able to refer to both the whole parameter and to its subcomponents thru proper names.
Fortunately, Haskell provides just that. This is known as the “as patterns”. More details here: SO-q30326249.
In your case, you could note your graph parameter as: g#(Graph(pairs)). Then, g is your graph object, and pairs is the corresponding list of type [(Vertex,OutNeighbors)].
You do not tell us about your contains function, but it is possible to infer that its type is:
contains :: Vertex -> Graph -> Bool
With that in mind, a version of your graph function taking an arbitrary iteration count can be written this way:
type Vertex = Int
type OutNeighbors = [Vertex]
data Graph = Graph [(Vertex,OutNeighbors)] deriving (Eq, Show, Read)
funcN :: Int -> Graph -> Graph
funcN iterCount g#(Graph(pairs)) =
if (iterCount <= 0) then g -- nothing to do
else let
gm1 = funcN (iterCount - 1) g -- recursion
fn = \(v,ngs) -> contains v gm1 -- filtration
in
Graph (filter fn pairs)
Using the same techniques, a tentative version of the contains function could be like this:
contains :: Vertex -> Graph -> Bool
contains v g#( Graph [] ) = False
contains v g#( Graph ((v0,ngs0):pairs) ) = (v == v0) || contains v (Graph(pairs))
This second function is a bit more complicated, because lists can be described thru 2 patterns, empty and non-empty.
Finally, a version of the function that does exactly 10 iterations can be written like this:
func10 :: Graph -> Graph
func10 g = funcN 10 g
or also in a more concise fashion using partial application (known in Haskell circles as currying):
func10 :: Graph -> Graph
func10 = funcN 10
Addendum: library style, using nest:
If for some reason “manual recursion” is frowned upon, it is possible to use instead the nest :: Int -> (a -> a) -> a -> a library function. It computes the Nth compositional power of a function, using recursion internally.
Then one just has to write the single iteration version of the graph function. The code looks like this:
import Data.Function.HT (nest)
funcNl :: Int -> Graph -> Graph
funcNl iterCount g0 = let
-- 2 local function definitions:
ftfn g1 (v, ngs) = contains v g1
func1 g2#(Graph(pairs)) = Graph (filter (ftfn g2) pairs)
in
nest iterCount func1 g0
I'm a little stuck on this assignment for OCAML. I'm trying to pass in a function and a value as a parameter into another function. For example, I have function called test that takes in (fun x -> x+x) and 3 as parameters. The function test should output 6, since 3 + 3 = 6. I know I can achieve something similar this by completing:
let func x = x + x;;
let a = func;;
let test a x = (a x);;
This way when I input, test a 5, I will get 10.
But when I change the statement to this, I get only the value I placed in for x. How do I get the (fun a -> a) to take in the value x?
let test a x = ((fun a -> a) x);;
fun a -> a is an anonymous identity function, it will always return its parameter. You could say:
let id = fun a -> a;;
id 3;;
=> 3
id (fun x -> x + x);;
=> (fun x -> x + x)
Note that in your
let test a x = ((fun a -> a) x);;
the first a and the other two as are different variables. The first one is never used again later. You can rewrite this line for easier understanding as:
let test a x = ((fun b -> b) x);;
How do I get the (fun a -> a) to take in the value x?
You are, and that's the problem. You're feeding your x to an identity function, and getting x back. What you want to do is feed the x to your a function, and that's what you did in your first attempt:
let func x = x + x;;
let test a x = a x;;
test func 3;;
=> 6
With functional languages in simple cases it is often helpful to write the expression in a form similar to lambda calculus and do the reductions manually (noting which reductions you are using). You can still use OCaml syntax as a simplified version of lambda calculus
So in the case of your example this would become:
let test a x = ((fun a -> a ) x);;
=> let test a x = ((fun b -> b ) x);; (* Variable renamed (alpha equivalence) *)
=> let test a y = ((fun b -> b ) y);; (* Variable renamed (alpha equivalence) *)
let func x = x + x;;
Note that these steps only serve to make sure, that we will later on have no variables with the same name, referring to different values. These steps can be left out, but I personally like working with unique variables much better.
test func 5
=> test (fun x -> x + x) 5 (* Variable func inserted (beta reduction) *)
=> (fun a y -> ((fun b -> b) y) (fun x -> x + x) 5 (* Variable test inserted *)
=> (fun y -> (fun b -> b) y) 5 (* Variable a inserted *)
=> ((fun b -> b) 5 (* Variable y inserted *)
=> 5 (* Variable b inserted *)
The final result is 5. Attempting this at first will seem very unusual and hard, but get's easier very fast. If you do something like this a couple of time you will get much better at understanding common functional patterns and reasoning about your program structure.
Have a look at this article for more examples on this.
Also note, that with a little more effort, this works backward as well. Although this usually is not as helpful as doing it in the same direction as the compiler.
Given a higher-order function like the following:
let call (f : unit -> 'a) = f()
And another function:
let incr i = i + 1
Is there a way to pass incr to call, without using a lambda: (fun () -> incr 1)?
Obviously, passing (incr 1) does not work, as the function is then "fully applied."
EDIT
To clarify: I'm wondering if there's a way to curry a function, such that it becomes a function: unit -> 'a.
You can define such a shortcut yourself:
let ap f x = fun () -> f x
call (ap incr 1)
If the function you want to transform happens to be a pure function, you can define the constant function instead:
let ct x _ = x (* const is reserved for future use :( *)
call (ct (incr 1))
It looks more like an attempt to add laziness to strict F# then some kind of currying.
And in fact there is a built in facility for that in F#: http://msdn.microsoft.com/en-us/library/dd233247.aspx - lazy keyword plus awkward Force:
Not sure if it's any better than explicit lambda, but still:
let incr i =
printf "incr is called with %i\n" i
i+1
let call (f : unit -> 'a) =
printf "call is called\n"
f()
let r = call <| (lazy incr 5).Force
printf "%A\n" r
I have an assignment and am currently caught in one section of what I'm trying to do. Without going in to specific detail here is the basic layout:
I'm given a data element, f, that holds four different types inside (each with their own purpose):
data F = F Float Int, Int
a function:
func :: F -> F-> Q
Which takes two data elements and (by simple calculations) returns a type that is now an updated version of one of the types in the first f.
I now have an entire list of these elements and need to run the given function using one data element and return the type's value (not the data element). My first analysis was to use a foldl function:
myfunc :: F -> [F] -> Q
myfunc y [] = func y y -- func deals with the same data element calls
myfunc y (x:xs) = foldl func y (x:xs)
however I keep getting the same error:
"Couldn't match expected type 'F' against inferred type 'Q'.
In the first argument of 'foldl', namely 'myfunc'
In the expression: foldl func y (x:xs)
I apologise for such an abstract analysis on my problem but could anyone give me an idea as to what I should do? Should I even use a fold function or is there recursion I'm not thinking about?
The type of foldl is
foldl :: (a -> b -> a) -> a -> [b] -> a
but the type of func is
-- # a -> b -> a
func :: F -> F -> Q
The type variable a cannot be simultaneously F and Q, thus the error.
If the Q can be converted to and from F, you could use
myfunc y xs = foldl (func . fromQ) (toQ y) xs
where
func . fromQ :: Q -> F -> Q
toQ y :: Q
xs :: [F]
so this satisfies all the type requirements, and will return the final Q.
maybe you need map?
map :: (f -> q) -> [f] -> [q]
it evaluates a function on each element in a list and gives a list of the results. I'm not sure why your function takes two Fs though, possibly to work with foldl?