I'm starting learning Ocaml, using hickey book, and I'm stuck on Exercise 3.4, part 9
let x x = x + 1 in x 2
The result of the operation is 3, but I don't understand why?
When you write let x x = ... you are defining a function called x which binds the name x to its argument.
Since you used let instead of let rec, the function doesn't know its own name, so as far as it knows, the only x worth knowing about is the one passed in as an argument.
Therefore when you call the function with x 2, it binds the value 2 to the name x and evaluates x+1, getting 3 as the result.
Related
I'm taking a MOOC (no credit). One of the assigned problems is to write a factorial function using a function that follows this:
(’a->’a)->(’a->bool)->’a->’a
I've created that function:
fun do_until (f, g) = fn x => case g(f x) of
false => f x
| _ => do_until(f,g) (f x);
but I've had difficulty using my do_until function to implement factorial.
The solution should follow this format I believe:
fun factorial x = (do_until (f, g)) x
The problem I see is that the 'g' function can only validate the result, and if validated, then return that result. Since the function type descriptors are fairly restrictive, it limits you from passing in a tuple to g, then verifying off part of the tuple and returning the other part. ie. (factorial, int to mult) then g would verify from #2 and return #1. Unfortunately the types prevent that. I'm starting to think using do_until as a helper function is impossible unless you compute the factorial some other way and then 'g' would just compare your result to that. Please let me know if I'm wrong and where to go next!
You have the wrong type – the function should be curried – and you will probably have more luck if you give the parameters more descriptive names than "f" and "g":
fun do_until next done x = if done x
then x
else do_until next done (next x)
Note that you can pass anything from factorial to do_until – for instance a tuple that holds your computation state – and then "take it apart" once do_until is done. (I suspect that this is why you're stuck.)
fun in_list (x : int, y : int list) =
if null y
then false
else if x=hd y then true
else in_list(x,tl y)
This is what my code currently looks like, it simply returns true if x appears in the the y list, false if not. The issue is I want it to be able to input "a" and ["a", "b", "c"] as well, or even have x be a list, and y be a list of lists. I am VERY new to ML (just started learning about it last week), and have searched for answers and cannot come up with anything.
If you change the first line to
fun in_list (x : ''a, y : ''a list) =
then it will behave as you want. Here ''a is an equality type variable that can stand for any type that supports the = operator.
You could also just leave out the types altogether and the most general correct type will be inferred.
Types can always be omitted in function declarations, with is only one exception: where overloading of operators could cause ambiguity. An example is
fun square x = x*x
because the type of x could be either int or real. (It will default to int, maybe not what you want.)
The point is that there is only one function hd. But the operator * can refer to two quite different functions.
I had a question on a hw that I got wrong and was wonder if someone could explain it.
Don't worry class is over just wanted to know why it's wrong. I asked a few other student and they had the same answer I had as well. I also look on line but all the examples I found are swap functions the X=1 is confusing me.
SUBROUTINE TEST(X,Y,Z)
X=1
Z=X+Y
RETURN
END
N=2
CALL TEST ( N,N,M)
WHAT WILL M BE IF PASSED BY REFERENCE?
WHAT WILL M BE IF PASSED BY VALUE-RESULT?
I got 3 for the first and 4 for the second question.
If you are passing by reference,
X=2, Y=2 when the subroutine is entered.
Then X gets set to 1, which will change Y to 1 as well since they share the same memory location, right? So that would make (X+Y) = 2 ==> Z = 2.
M=2.
By value:
X=2, Y=2, but then X get sets to 1 but that doesn't change Y since this is by value. That makes Z = 3.
M =3.
I am reading the book by jason and do not quite understand the following program:
let fact2 i =
let rec loop accum i =
if i = 0 then
accum
else
loop (i * accum) (i - 1)
in
loop 1
How is accum initialized?
What is the meaning of the last two lines (i.e. in loop 1)? loop has two parameters. why only one is passed here (i.e. loop 1).
Thank you very much!!!
I think that it's a mistake in implementation. Last line should be
loop 1 i
Integer 1 initialises accum from loop function and i initializes i in the same function.
Note that the lines starting with let rec loop accum i define a function. So accum is initialized when the function is called. This happens in the last line. As Kakadu points out, there's a transcription error in your post. The last line should say loop 1 i which (in essence) initializes accum to 1.
I think you have an extra "i" in the first line. That makes fact2 take an extra argument which is never used. Instead it should read:
let fact2 =
The last line that says "loop 1" is often called a partial application.
Ocaml usually uses curried functions, so another way of thinking of it is that loop actually takes one parameter and returns a function which in turn takes another parameter and returns an int.
In this particualar case, the type of (loop 1) is int -> int meaning it takes an int and returns an int. The type of loop is int -> int -> int meaning it takes an int and return an int -> int. It can also be written more explicitly as int -> (int -> int) since -> is right-associative.
To answer the other question, accum is initialized by passing 1 to loop.
Here is more information on currying: http://en.wikipedia.org/wiki/Currying
And of course, adding another "i" as others are suggesting would also work, but then you'd still be confused when others left it out.
It may help to think of let f x y = ... as being equivalent to let f = fun x -> fun y -> ...
And of course let f x = g x is the same as let f = g except the former will only work when g is a function.
I'm trying to figure out how to implement fixed point iteration in Ocaml. That is, given a function f and an x, I want to calculate what the final value of what f(f(f(x)...)) will be.
So for example, if my function is x/2 and my x=50, my answer should be 0.
So far, I have
let rec computed_fixed_point eq f x =
if (x == f x) then
x
else
computed_fixed_point eq f (f x)
This works for the function x/2 and x=50 (giving me 0), but for functions that go off to infinity or something other than 0, it doesn't seem to work.
Can another give me some advice? Thanks!
It's a little hard to understand the rationale of this problem. Not every function is going to have a fixed point. For example fun x -> (x + 1) mod 5. Not every function with a fixed point will reach the fixed point by repeated application from a distinct starting point. (I just did some googling, and fixed points like this are called "attractive fixed points".)
Here are some comments:
You shouldn't use ==, which is the physical equality operator. You possibly want to use =, equality of values.
However, I don't see what the eq parameter is for. Perhaps the caller is allowed to specify what equality to use. If so, you should use this instead of ==.