How can I change user defined type to int? - ocaml

type t=Num of int (* need to change to Num2 of int *)
type e = Num of int
| Add of e*e
let rec intp e : t =
| Num n -> t (n)
| Add (e1, e2) -> int (intp e1) + int (intp e2)
I want to add two variable that is user defined type but they can't add user defined types so I cast type using int () but Unbound value int occured. How can I change type t to int?

Your example code doesn't has two definitions of Num. I'll assume the second one is what you want.
In general the way to extract a value is by pattern matching. Here is a function that returns the int inside a value of your type e if it is Num and 0 if it is Add:
let int_val x = match x with Num i -> i | Add _ -> 0
You can use pattern matching in a similar way in your code to extract the int value from Num i.

If you want intp to return type t, you have to use its Num constructor. If we run intp on an e value constructed with Num2, we extract its int value with pattern matching and construct a t value with Num.
Knowing intp will eventually return a t value, we can use pattern matching on the result of recursively calling intp on each of Add's subexpressions to extract the two int values, then add them together and construct a t value with Num.
type t = Num of int
type e =
| Num2 of int
| Add of e * e
let rec intp = function
| Num2 n -> Num n
| Add (e1, e2) ->
let Num n1 = intp e1 in
let Num n2 = intp e2 in
Num (n1 + n2)
utop # intp ## Add (Num2 9, Add (Num2 3, Num2 1));;
- : t = Num 13
Further reading
This has the downside of not being tail-recursive. But it's essentially a binary tree, and ivg has written a very good guide to tail recursion that includes tail-recursion on trees. It's a heck of a ride, but it might help you take this function to the next level.

Related

f# concatenate list of objects

type Googol = {
number : float
power : float
result : float
}
let generatePowers (n:float) : list<Googol> =
let rec powerInner (n:float) (p:float) (acc : list<Googol>) =
match n with
| p when p <= 1.0 -> acc
| p when p > 1.0 -> powerInner n (p-1.0) ([{ number=n; power=p; result=n**p}]#acc)
let rec numberInner (n:float) (acc : list<Googol>) =
match n with
| n when n <=1.0 -> acc
| n when n >1.0 -> numberInner (n-1.0) ((powerInner n [])#acc)
numberInner n []
ProjectEuler.fsx(311,50): error FS0001: This expression was expected to have type
'Googol list'
but here has type
'Googol list -> Googol list'
I am trying to solve this problem -> https://projecteuler.net/problem=56 | but for this I need to generate powers below n < 100. When I try to concatenate [{ number=n; power=p; result=n**p}]#acc
these lists I get the error above. Explain please why error says 'Googol list -> Googol list' is in the function, does I plug a function as a parameter to the function or I plug the actual list when just after concatenation. Is # a function?
This looks like homework or practice, so first I'll give some hints to move on. Finally I'll show a version that seems to work, and then tell how I would approach the problem.
The task is to find the number a ** b, for a and b less than 100, that has the highest sum of its own digits.
The first problem is that float won't give us all the digits of a ** b, so that type is useless to solve the problem. To fix that, we turn to the BigInteger type, and the BigInteger.Pow function. Then we get a 1 followed by 200 zeroes if we run the following snippet, just like it says in the problem description.
let x: bigint = BigInteger.Pow (100I, 100)
let x: string = string x
printfn "s=%s" x
To get useful results, change the Googol type so that it uses bigint, except for power that should be an int.
Why are the functions powerInner and numberInner inside the function generatePowers? This doesn't seem to have a specific purpose, so I suggest moving them out to make this clearer.
The function powerInner do a match on n, but then goes on to name the results p, which shadows the p parameter so that it is unused. Ok, the intention here is probably to match on p rather than n, so just fix that, and then the shadowing of the p parameter is perfectly fine.
The tests first on <= 1 and then on > 1 causes incomplete matches. If the first line checks that the number is less or equal to one, then it must the greater than one in the next line. So just use n -> without the when to fix that. I also suspect you want to test <= 0 instead of 1.
This
[{ number=n; power=p; result=n**p}]#acc
can be just
{ number=n; power=p; result=n**p } :: acc
and here
(powerInner n [])
I suspect you just need a starting value for the power, which would be 99
(powerInner n 99 [])
SPOILER WARNING
After a bit of tinkering, this is what I ended up with, and it seems to print out a useful list of numbers. Note that in order to not run through all 99 by 99 results with printouts, I've used low starting numbers 3 and 5 for the countdowns here, so we get some simple printout we can study for analysis.
type Googol = { number: bigint; power: int; result: bigint }
let rec powerInner (n: bigint) (p: int) (acc: Googol list) =
match p with
| p when p <= 0 -> acc
| p ->
let newNumber = { number = n; power = p; result = n ** p }
printfn "newNumber=%0A" newNumber
powerInner n (p - 1) (newNumber :: acc)
let rec numberInner (n: bigint) (acc: Googol list) =
match n with
| n when n <= 0I -> acc
| n -> numberInner (n - 1I) ((powerInner n 5 []) # acc)
let generatePowers (n: bigint) : Googol list =
numberInner n []
let powers = generatePowers 3I
I'm not sure if this solution is correct. I'd do it differently anyway.
I would simply loop through a and b in two loops, one inside the other. For each a ** b I would convert the result to a string, and then sum the digits of the string. Then I'd simply use a mutable to hold on to whichever result is the highest. The same could be achieved in a more functional way with one of those fancy List functions.
You're missing a parameter here:
| n when n >1.0 -> numberInner (n-1.0) ((powerInner n [])#acc)
^^^^^^^^^^^^^^^
here
powerInner is defined with three parameters, but you're only passing two.
In F# it is not technically illegal to pass fewer parameters than defined. If you do that, the result will be a function that "expects" the remaining parameters. For example:
let f : int -> int -> string
let x = f 42
// Here, x : int -> string
let y = x 5
// Here, y : string
So in your case omitting the last parameter makes the resulting type Googol list -> Googol list, which then turns out to be incompatible with the type Googol list expected by operator #. Which is what the compiler is telling you in the error message.

OCaml Function to Perform Differentiation

I'm currently studying the language OCaml, and was solving an exercise problem when I came across a question that I can't seem to wrap my head around. Here's the question:
"Write a function differentiate : expression * string -> expression that receives an algebraic equation and a string as an argument, and returns the differentiated version of the argument equation.
For example, diff (Add [Mult [Int 3 ; Exp("x", 2)] ; Mult [Int 6 ; Variable "x"], "x") should produce the result:
Add [Mult [Int 6 ; Variable "x"] ; Int 6]"
Here's the code that I wrote:
type expression =
| Int of int
| Variable of string
| Exponent of string * int
| Mult of expression list
| Add of expression list
let rec differentiate : expression * string -> expression
= fun (exp, x) ->
match exp with
| Int a -> Int 0
| Variable a -> if (a = x) then Int 1 else Variable a
| Exponent (a, b) -> if (a = x) then
match b with
| 2 -> Mult [Int 2; Variable a]
| _ -> Mult [Int b; Exponent (a, b - 1)]
else Int 0
| Mult [Int a; Int b] -> Const (a * b)
| Mult (Int a::[Variable b]) -> Mult (Int a::[differentiate (Variable b, x)])
| Mult (Int a::[Exponent (e1, e2)]) -> Mult (Int a::[differentiate (Exponent (e1, e2),
x)])
| Mult (Int a::[Mult (Int b :: l)]) -> Mult (Int (a * b) :: l)
| Add l -> match l with
| [] -> l
| hd::tl -> Add ((differentiate (hd, x)) :: tl)
;;
My algorithm is basically performing rigorous pattern matching. More specifically, for Mult, the first element is always an integer, so I performed pattern matching on the second element. For Add, my plan was to write the function so that it performs the function differentiate on each element. Here are the specific problems I would like to ask about.
This code actually gives me an error on the Add l portion of pattern matching. The error message states: Error: This expression has type (expression list) but an expression was expected of type (expression). As far as my understanding reaches, I am certain that Add l is an expression type, not an expression list type. Why is this error message produced?
I am not sure how to perform recursion in this specific example. My initial thought is that the function should only execute once each, otherwise the result would consist mainly of Int 0's or Int 1's. Please correct me if I'm wrong.
Any feedback is greatly appreciated. Thank you!

Define nested functions in standard ml

I am new in sml. I tried to convert int to int list. For example, assume that there is an input 1234, then output is a list like [1,2,3,4]. And my question is, how can I type nested functions in sml? let in end? There is my code.
fun digit (a : int): int =
let
fun size (a) = if a < 0 then nil
else x = Int.toString x then digit s = size(x)
fun insert (num, nil) = [num]
| insert (num,xs) = x :: insert ()
fun convert (a, s) = if s < 0 then nil
else insert (a / (10*(s - 1)), xs)
then convert(a - (10*(s - 1), s - 1)
in
end
Nested functions are just one way to split up your workload in multiple, smaller parts. Another option is non-nested library functions. The main differences are that functions that aren't nested don't inherit its parent's variable scope, so they can only work with their own input, and functions that are nested aren't available anywhere else and can't be re-used. Let's say you're giving this problem a first stab:
fun digit_meh n = if n < 10 then [n] else n mod 10 :: digit_meh (n div 10)
And you realize it isn't doing exactly as you want:
- digit_meh 1234;
> val it = [4, 3, 2, 1] : int list
You could remove the most significant digit first, but the calculation isn't as trivial as n mod 10, since it depends on the number of digits.
You could generate this list and then reverse it:
fun digit n = rev (digit_meh n)
But the function digit_meh isn't particularly useful outside of this function, so it could be hidden using local-in-end or let-in-end:
local
fun digit_meh n = if n < 10 then [n] else n mod 10 :: digit_meh (n div 10)
in
val digit = rev o digit_meh
end
fun digit n =
let fun meh n = if n < 10 then [n] else n mod 10 :: meh (n div 10)
in rev (meh n) end
Do notice that the function meh's copy of n shadows digit's copy of n.
For clarity you could also name the variables differently.
Or you could look at how rev is doing its thing and do that. It basically treats its input as a stack and puts the top element in a new stack recursively so that the top becomes the bottom, much like StackOverflow's logo would look like if it jumped out and landed upside down like a slinky spring:
fun rev L =
let fun rev_stack [] result = result
| rev_stack (x::xs) result = rev_stack xs (x::result)
in rev_stack L [] end
Because the result is accumulated in an additional argument, and rev should only take a single argument, nesting a function with an extra accumulating argument is a really useful trick.
You can mimic this behavior, too:
fun digit N =
let fun digit_stack n result =
if n < 10
then n::result
else digit_stack (n div 10) (n mod 10::result)
in f N [] end
This way, we continue to treat the least significant digit first, but we put it in the stack result which means it ends up at the bottom / end. So we don't need to call rev and save that iteration of the list.
In practice, you don't have to hide helper functions using either local-in-end or let-in-end; while it can be useful in the case of let-in-end to inherit a parent function's scope, it is not necessary to hide your functions once you start using modules with opaque signatures (the :> operator):
signature DIGIT =
sig
val digit : int -> int list
end
structure Digit :> DIGIT =
struct
fun digit_stack n result =
if n < 10
then n::result
else digit_stack (n div 10) (n mod 10::result)
fun digit n = digit_stack n []
end
As this is entered into a REPL, only the relevant function is available outside of the module:
> structure Digit : {val digit : int -> int list}
signature DIGIT = {val digit : int -> int list}
- Digit.digit 1234;
> val it = [1, 2, 3, 4] : int list
fun aFunctionCallingF2F3 someVariables =
let
<define some functions and local variables here>
fun F2 ...
fun F3 ...
val v1 ...
val v2 ...
in
<Make use of the functions/variables you defined above and `someVariables`>
end
For example,
fun areaCirle r:real =
let fun square x:real = x*x
val pi = 3.14
in
pi * square r
end
Or define functions you need to call beforehand if they are not mutually recursive. If they are mutually recursive, you can look up the keyword and.
fun F2 ...
fun F3 ...
fun aFunctionCallingF2F3 = <make use of F2 F3 directly>
For example,
fun square x:real = x * x
fun areaCircle r = square r * 3.14
Note that you cannot do
fun areaCircle r = square r * 3.14
fun square x:real = x * x
square needs to be defined before areaCircle.

Ocaml: add up all the integers in an int list and output it as an int Option

. Write a function that takes an integer list and return sum of all elements of the list. If the list is empty then return None.
This is my code now:
let rec sum (xs: int list) =
match xs with
| [] -> None
| [x] -> Some x
| hd::tl -> let m = (hd + (sum tl)) in
Some m
;;
The problem is that I can't seem to find a way to add up the last element without getting an error.
This is my error.
Error: This expression has type int but an expression was expected of type 'a option.
Your recursive call to sum does indeed return an int option. You know this because you're the author of the function, and you coded it up to return that type :-) You can either write a helper function that returns an int, or you can extract the int from the return value of sum, something like this:
let tlsum =
match sum tl with
| None -> (* figure this part out *)
| Some n -> (* figure this part out *)
You can define the addition of two int option.
let sum l =
let (+) a b =
match (a,b) with
| (None,x) | (x,None) -> x
| (Some x,Some y) -> Some (x+y)
in
let convert a = Some a in
let opt_l=List.map convert l in
List.fold_left (+) None opt_l
Test
# sum [];;
- : int option = None
# sum [1;2];;
- : int option = Some 3
That looks like an assignment so I'll be vague:
The easiest way to do that is probably to first define a function of type int list -> int that returns the "normal" sum (with 0 for the empty case). That function will be recursive and 0 will correspond to the base case.
Then write another function of type int list -> int option that checks whether its argument is empty or not and does the right thing based on that.
Trying to write the recursion directly probably is not a good idea since there are two cases when you will need to handle []: when it's the only element in the list, and when it's at the end of a nonempty list.

OCaml variable counting

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.