fun count_wcs p =
let
val count = 0
in
g (fn () => count + 1) (fn y => 1) p
end
I'm doing homework and we're not supposed to use mutations, this doesn't reassign the value to anything but it doesn't feel right. Please, don't say what is the right way to do this, because I'm supposed to figure this out.
datatype pattern = Wildcard
| Variable of string
| UnitP
| ConstP of int
| TupleP of pattern list
| ConstructorP of string * pattern
fun g f1 f2 p =
let
val r = g f1 f2
in
case p of
Wildcard => f1 ()
| Variable x => f2 x
| TupleP ps => List.foldl (fn (p,i) => (r p) + i) 0 ps
| ConstructorP(_,p) => r p
| _ => 0
end
This function g has to receive a type unit -> int function as the first argument. I checked the count after I called the function and got 0, so it is ok to write it like this, right? But still, it does feel sloppy.
Added the context (function g and the datatype used). The function count_wcs is supposed to count the number a Wildcard pattern appears in a pattern.
This does not count as a mutation, but it does resemble what you might do if you had them and is probably not going to work, depending on what it is you're doing. Mutations require references and they're made with ref and are de-referenced with !. So just stick away from those. :-)
You're doing something that will be of little benefit:
let
val count = 0
in
...
end
will bind count to 0, but will never cause count to have any other value; I presume that you want to eventually have that count increases. If it had been a reference, val count = ref 0, you could increment it by doing count := !count + 1, but since it's not, you have to make count a variable of some function for it to change.
For example:
fun count_4s ([], count) = count
| count_4s (x::xs, count) = count_4s (xs, if x = 4 then count + 1 else count)
In each call count is constant, but in each subsequent, recursive call it is possibly incremented.
This function g has to receive a type unit -> int function as first argument.
...
g (fn () => count + 1) (fn y => 1) p
...
[...] But still it does feel sloppy.
Assuming that g's first arguments have no side-effects and do not throw exceptions and do not loop forever, all they can do is return the same thing on every call. This makes them rather boring. Typically functions that either take as input or return () : unit do something else, like read or write from a source external to the program.
I wouldn't call it sloppy. Just a bit weird, without knowing the context.
It's very easy to identify mutation in standard ML - if you don't use ref variables and assign them new values with :=, it's not mutation.
And you don't, so you aren't mutating anything.
Also, your function can be simplified to
fun count_wildcards p = g (fn () => 1) (fn _ => 1) p
which makes it even clearer that nothing gets mutated.
(It's not at all clear what it's supposed to accomplish, so it's impossible to tell whether your solution is correct.)
Related
I want to calculate f(..f(x)) p times. The following is my code.
let rec function f x p = if p = 0 then x else function f (f x) p-1;;
I wonder how I should make it right.
This is very close, but your code has syntax errors that are going to make it hard to make progress. I think the main problem is that you're using function as an identifier, but it is a keyword in OCaml. If you change to myfun, things should start working quite a bit better.
You also need to watch your precedences. The following code:
f a b-1
is parsed like this:
(f a b) - 1
not like this:
f a (b - 1)
You need to write the parentheses explicitly to get this second parse.
You can define a recursive function ch to apply a function f many times (Church numeral??) as follows:
let rec ch f p x = if p = 0 then x else f (ch f (p-1) x);;
The problems in your original code are that:
need to name the function as something, such as ch here.
need to call the same function ch to get the recursion going as shown above. In your original code, there is no recursion.
Example
let p1 x = x + 1 ;;
ch p1 3 1 ;;
this will give you
- : int = 3
as intended.
How is it possible to composite function f n times in ML?
composite two times;f(fx)
composite three times;f(f(fx)))
composite n times; f(f(f(f.....(fx)))))))
I have tried;
fun composite f g =
let h x = f(g x)
in h end;
fun repeat f n =
if n = 0 then x
else composite f repeat(f (n - 1));
Thank you
When you write recursive functions, divide your problem into general, recursive cases, and base cases that don't require recursion. For example, composing a function with itself n times sounds like the base case might be either when n = 0 or when n = 1 (either could work; I'll get back to that).
I'd encourage pattern matching, but when recursing integers, if-then-else do seem just as simple. In any case, all the examples have been written in both styles. A simple skeleton might be:
fun repeat f n =
if n = 0
then ?
else ?
fun repeat f 0 = ?
| repeat f 1 = ?
| repeat f n = ?
On functions that return functions
I imagine some of the difficulty here is that repeat must return a function. Syntactically you can achieve that in various ways. Like John suggests, you might write it by extending repeat with x:
fun repeat f n x =
if n = 1
then f x
else ...
fun repeat f 1 x = f x
| repeat f n x = ...
to which the natural, but slightly weird, interpretation is "repeat is a function that takes three arguments; the function f, the number of times it must be applied n, and f's argument x (?!)".
Alternatively, one might also write it like
fun repeat f n =
if n = 1
then (fn x => f x)
else ...
fun repeat f 1 = (fn x => f x)
| repeat f n = ...
which might be interpreted like "repeat is a function that takes two arguments; the function f and the number of times it must be applied n, and returns a function that applies f to its argument n times."
Those definitions are really equivalent. You'll see that by translating the description into types:
val repeat : ('a -> 'a) -> int -> 'a -> 'a
val repeat : ('a -> 'a) -> int -> ('a -> 'a)
That last parenthesis is implied in the first type signature.
Sometimes it helps to think of functions with many curried arguments as "functions with many arguments", and other times it helps to think of them as "functions that return functions that take yet other arguments". And repeat seems to be a mixture of this; n is best thought of as "a second argument", but x is best thought of as "the argument that the function we're returning takes".
With this preference, and a preference for pattern matching, my recommended basis would be:
fun repeat f 0 = ...
| repeat f 1 = f
| repeat f n = ...
since (fn x => f x) and f are really one and the same function.
On the base case and the recursive case
You write:
fun repeat f n =
if n = 0 then x
else composite f repeat(f (n - 1));
The x in then x has the wrong type, since repeat f n must return a function. See above.
The case when applying f zero times is a little tricky. Whatever the result is, it should be the case that repeat f 0 should give the same result regardless of f. Or put differently, that f isn't applied, although the repeat f 0 does need to return something.
On the recursive case, really, you're just messing up the parentheses. John revealed the o operator that is Standard ML's built-in version of composite which I'll prefer, too:
composite f (repeat f (n-1))
f o repeat f (n-1)
What you need to know about parentheses in Standard ML: You add them mostly to group things. When you write composite f repeat (f (n-1)), what you're saying is: "composite is a three-argument function that takes f, repeat and f (n-1) as an argument" and "f is a function that takes integers as arguments."
When what you really wanted to say was "composite takes f and the result of composing f with itself n–1 times, and composes those." It's a classic mistake when you come from languages that expect function calls to look like foo(arg1, arg, arg3) and one thinks this translates into foo(arg1 arg arg3) when in fact you wanted foo arg1 arg2 arg3. In Standard ML, this parenthesis forces arg1 to be treated as a function and applies it to arg2 and arg3, and applies foo to the result of that. Whoops!
Your ideas are close to being correct. You could use currying to make them work:
fun composite f g x = f(g(x));
SML infers its type as:
val composite = fn : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b
which is exactly right for composition. Function application is left-associative, so
composite f g x
parses as
(composite f g) x
the function definition thus reads as giving the meaning of applying the function (composite f g) to an argument x. The meaning is, of course, to return the value f(g(x)).
You can test it:
fun square x = x*x
fun increment x = x + 1
val h = composite increment square
Then e.g. h 5 evaluates to 26 as expected.
A similar tweak works for your second definition. It could begin:
fun repeat f n x =
since this seems like homework, I'll leave the details to you, but your current attempt is rather close to a correct solution.
Having said all this, you should know that composition is a built-in operator in SML, denoted by the lowercase o, and that (op o) could be used in your second definition in place of composite.
I am trying to achieve the following: Finding the element at a specific index.
So if I had a list of [5; 2; 3; 6] and ask for the element at index 2, it would return 3.
let counter = 0;;
let increase_counter c = c + 1;;
let rec get_val x n = match x with
[] -> -1
| (h::t) ->
if (counter = n) then
h
else
increase_counter counter ; get_val t n
;;
But this code is giving me a bug saying that -1 is not of type 'unit'?
As Jeffrey Scofield said, you should write let counter = ref 0 to make counter mutable. Now, you can use the built in incr function to increment it (equivalent to counter := !counter + 1), and you'll get its value with !counter.
There is also a problem in your algorithm : if the counter is equal to n, you return the head of the list... you mean : if the head of the list is equal to n, you return the counter.
Your program is then :
let counter = ref 0;;
let rec get_val x n = match x with
[] -> -1
| (h::t) ->
if (h = n) then
!counter
else
begin incr counter ; get_val t n end
;;
Note that I've added begin and end around the else block so it can be interpreted as a sequence of instructions.
Your program now works, but it is not the best way to solve this problem with ocaml.
You should write something like
let get_val x n =
let rec get_val_aux x n counter = match x with
| [] -> -1
| h :: _ when h = n -> counter
| _ :: t -> get_val_aux t n (succ counter)
in
get_val_aux x n 0
;;
Here, we add a parameter to the get_val_aux function which we increment at each call. This function is nested within the get_val function to hide this additional parameter which is initialized with 0 on the first call.
Instead of using an if statement, we use the when condition to know when the element has been found, and add a new case to match the last case (not found). Note the use of the _ wildcard to avoid an unused variable.
The succ function (for successor) only adds 1 to its parameter. It is equivalent to counter + 1.
There are many problems with this code. If you ignore your immediate problem for a moment, you are treating OCaml variables like the variables of an imperative language. However, OCaml variables are immutable. This function
let increase_counter c = c + 1
Doesn't change the value of any variable. It just returns a number 1 bigger than what you give it.
The only error I get from the toplevel when I enter your code is for this expression:
increase_counter counter ; get_val t n
The compiler is warning you that the expression before ; is supposed to be executed for its side effects. I.e., it should almost always have type unit. Since (as I say) your function increase_counter returns an int, the compiler is warning you about this.
I have this function that takes a list of lists of strings and a string and then return a list of all the elements in each list that contains the string passed but without the string passed.
myfilter([["a","b"],["c","d"],["e","a","x"]], "a") -> ["b","e","x"]
fun myfilter(list : string list list, s : string) =
case list of
[] => []
|xs::xs' => case all_except_option(s, xs) of (* helper function that does it for a string and a list of strings *)
NONE => []
|SOME n => if n = xs
then myfilter(xs',s)
else n#myfilter(xs',s)
Now this is as you can see is a recursive function and I want to convert it to a tail recursive function. I am familiar with the examples of tail recursion but I am failing to see how I can do it in the function above
When you think tail recursive, the next thing you think should be "accumulator".
The reason a function is not tail recursive is that it has to call itself to obtain some result, and then do something with that result. If we can move that calculation into the recursive call, then it's tail recursive.
In this case, the calculation you're making is that you're putting two lists together. So the solution would be a function declared inside a let ... in ... end, that takes a third parameter - an accumulator. Then you can add items to the accumulator as you go.
A good example is a tail-recursive factorial function. Here's the normal factorial function:
fun fact 0 = 1
| fact x = x * fact (x-1)
To make it tail-recursive, we define a local function which takes an accumulator, and do the multiplication there.
fun fact x =
let
fun fact' 0 acc = acc
| fact' x acc = fact (x-1) (x*acc)
in
fact' x 1
end
We use 1 as the starting value for the accumulator, because multiplying with 1 has no effect.
Okay, so other than that, there is a little thing you can do to improve your code. I've noticed a lot of people here that do this:
fun foo xs =
case xs of
[] => ...
| (x::xs) => ...
Where it would be much nicer to just do:
fun foo [] = ...
| foo (x::xs) = ...
Given this following code (which does not work):
fun func() =
val decimal = 0 (* the final result *)
val multiple = 0 (* keeps track of multiples, eg. In XXV, X would be a multiple *)
val current = 0 (* the digit currently being processed *)
val top = 0 (* value of the last element in the list *)
val last_add = 0 (* the last digit that wasn't a multiple, or subtraction operation *)
val last_sub = 0
val problem = 0 (* if value is 1 then there is a problem with the input *)
val myList = [1,2,3,4,5] (* the list has more values *)
val current = tl(myList) (* grab the last element from the list *)
val myList = tl(myList) (* remove the last element from the list *)
val top = tl(myList) (* grab the value at the end of the list *)
while (not(myList = [])) (* run while the list is not empty *)
if ( (not(myList = [])) andalso (current > top))
then
val decimal = decimal + current - top
val last_sub = top;
val myList = tl(myList)
else
if ( (myList = []) andalso (current = top))
then val decimal = decimal + current
val multiple = multiple + 1
else
if (last_sub = current)
then val problem = 1
else
val decimal = decimal + current
val multiple = 0
val last_add = current
This is only a partial code , which doesn't work at the moment , since the val is not
possible within an if statement .
I want to run in a while loop , how can I do that in ML ?
How can I assign and reassign values into variables that were previously declared in ML ?
The val keyword is not possible within the IF condition , so I cannot update the variables , any idea how to solve that ?
Regards
How can I assign and reassign values into variables that were
previously declared in ML ?
You cannot assign to variables after they are declared in ML.
The val keyword is not possible within the IF condition , so I cannot
update the variables , any idea how to solve that ?
Except at the top level, you usually use val and fun inside a let:
let
val x = blah blah
val y = blah blah
fun f x y = blah blah
in
some expression
end
However, note that this creates a new variable (which may hide any existing variable of the same name), which exists inside the scope of the body of the let. As said before, you cannot assign to an existing variable.
I want to run in a while loop , how can I do that in ML ?
You are almost there. The syntax is while condition do ( ... ). But a while loop is useless without mutable state.
If you want mutable state, you can use a mutable data structure. The language provides a simple "mutable cell" called ref: you create it by passing the initial value to the ref function, you get the current value with the ! operator, and you set a new value with the := operator. You also have to remember that if you want to run multiple imperative "statements", you must separate them with the ; operator, and possibly enclose the whole "block" of statements in parentheses due to precedence issues.
But using while loops and mutable state is really not the right way to go here. You are using a functional language, and it would be much better for you to re-write your algorithm to be purely functional. It's not hard to do. You would turn the body of your while loop into a tail-recursive helper function, and the "variables" that change between iterations of the loop would become arguments to this function. Instead of trying to "set" the values of these variables, it would simply recursively call itself with the new values for the next iteration. If it's tail-recursive, it's equivalent to iteration memory-wise.