I need to create a function that returns the result of calculating expressions of a created type:
type expr =
VarX
| VarY
| Sine of expr
| Cosine of expr
| Average of expr * expr
| Times of expr * expr
| Thresh of expr * expr * expr * expr
here is what the function is supposed to do :
eval : expr * float * float -> float that takes an triple (e,x,y) and evaluates the expression e at the point x,y . x and y are going to be between -1 and 1 and the result of the function will be in the same interval. Once you have implemented the function, you should get the following behavior at the OCaml prompt:
# eval (Sine(Average(VarX,VarY)),0.5,-0.5);;
- :float = 0.0
Here is the function that I wrote it needs to return a float:
let rec eval (e,x,y) = match e with
VarX -> x*1.0
|VarY ->y*1.0
|Sine expr -> sin(pi* eval (expr,x,y))
|Cosine expr -> cos( pi* eval (expr,x,y))
|Average (expr1, expr2) -> (eval (expr1,x,y)+eval (expr2,x,y))/2.0
|Times (expr1, expr2) -> (eval (expr1,x,y))*(eval (expr2,x,y))
|Thresh (expr1, expr2, expr3, expr4) ->if((eval (expr1,x,y))<(eval (expr2,x,y)))then (eval (expr3,x,y)) else(eval (expr4,x,y));;
this is the error that i get,
Error: This expression has type float but an expression was expected of type
int
how do i make the function return a float, i know it needs to think that every return value for each case needs to be a float but im not sure how to do that
The operator for multiplying two floats is *.. The operator for adding two floats is +.. And, the operator for dividing two floats is /.
Related
Sorry about the "what am I missing here" style of question here, but I'm just missing something here.
I was trying to understand how GADTs work in OCaml, I define the following (in utop):
type value =
| Bool : bool -> value
| Int : int -> value
;;
type _ value =
| Bool : bool -> bool value
| Int : int -> int value
;;
type _ expr =
| Value : 'a value -> 'a expr
| If : bool expr * 'a expr * 'a expr -> 'a expr
| Lt : 'a expr * 'a expr -> bool expr
| Eq : 'a expr * 'a expr -> bool expr
| Gt : 'a expr * 'a expr -> bool expr
;;
I defined an eval function:
let rec eval : type a. a expr -> a = function
| Value (Int i) -> i
| Value (Bool b) -> b
| Lt (a, b) -> (eval a) < (eval b)
| Gt (a, b) -> (eval a) > (eval b)
| Eq (a, b) -> (eval a) = (eval b)
| If (c, a, b) -> if eval c then (eval a) else (eval b)
;;
but got an error:
Line 4, characters 15-23:
Error: This expression has type $Lt_'a but an expression was expected of type
int
What exactly does this mean?
Just to test further, I modified the expression GADT to be:
type _ expr =
| Value : 'a value -> 'a expr
| If : bool expr * 'a expr * 'a expr -> 'a expr
| Lt : int expr * int expr -> bool expr
| Eq : 'a expr * 'a expr -> bool expr
| Gt : int expr * int expr -> bool expr
;;
and then I see
Line 6, characters 15-23:
Error: This expression has type $Eq_'a but an expression was expected of type
int
When I finally modify it to be
type _ expr =
| Value : 'a value -> 'a expr
| If : bool expr * 'a expr * 'a expr -> 'a expr
| Lt : int expr * int expr -> bool expr
| Eq : int expr * int expr -> bool expr
| Gt : int expr * int expr -> bool expr
;;
it works fine.
Update (more context):
Ocaml version: 4.08.1
Libraries opened during this session: Base
Update (solution):
it turned out to be (as mentioned in the first line of the selected answer) because I had previously, within utop run open Base ;;
In a fresh session I'm able to enter the types initially mentioned and eval is happy with that.
The direct cause of the error is that you are using a library (maybe Base or Core?) that shadows the polymorphic comparison operators (<,<=,=,>=,>) and replace them with integer comparison operators.
Concerning the error message, when you pattern match a GADT constructor with existential types,
| Lt (a, b) -> (eval a) < (eval b)
the typechecker introduces new types to represent the existential types.
Here, in the (original) definition of Lt,
| Lt : 'a expr * 'a expr -> bool expr
there is one existentially quantified type variable: 'a.
When pattern matching on Lt, we need to replace this type variable with
a new type. Moreover, it is quite useful in error message to try to pick
a meaningful name for this type. To do so, the typechecker constructs a
new type name piece by piece as $ + Lt + 'a:
$: to mark an existential type
Lt: to indicate that it was introduced by the constructor Lt
a: to remember that the existential type variable was named 'a in the definition of the constructor
In other words, in the pattern match above, we have something akin to
| Lt ( (a: $Lt_'a eval), (b: $Lt_'a eval)) -> (eval a) < (eval b)
And when typing:
(eval a) < (eval b)
the typechecker compare the type of <: int -> int with the type of eval a: $Lt_'a and outputs your original error message:
Line 4, characters 15-23:
Error: This expression has type $Lt_'a but an expression was expected of type
int
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!
type exp = V of var
| P of var * exp
and var = string
I'm building a binary reference tree where the right leaf nodes lookup for the ones on the left leaf nodes, and returns true if all the right leaf nodes match with some left leaf nodes.
let rec ctree : exp * exp -> bool
=fun (e1,e2) -> match e2 with
| P (x,y) -> match y with
| P (a,b) -> if (ctree(a,b)) then true else ctree(x,b)
| V a -> if a=x then true else ctree(e1,y)
| V x -> e1=x
But here, I'm keep getting error at line 5:
| V a -> if a=x then true else ctree(e1,y)
The e1 here has a type exp, and it should be that way, but the compiler keeps telling me that it should be a type var=string. Also, for line 6,
V x -> e1=x
it's telling me that there should be type var=string instead of e1 again.
Can anyone tell me why it's getting the error?
When you have two nested match expressions, it's not clear where the nesting ends. You need to use parentheses around the inner match. Something like this might work:
let rec ctree : exp * exp -> bool =
fun (e1,e2) -> match e2 with
| P (x,y) ->
(match y with
| P (a,b) -> if (ctree(a,b)) then true else ctree(x,b)
| V a -> if a=x then true else ctree(e1,y)
)
| V x -> e1=x
Second, your type for the function is exp * exp -> bool, which says that e1 is of type exp. At the end of the function you have this:
| V x -> e1 = x
Since x is the value of a V constructor, it must be a string. But then e1 = x only makes sense if e1 is a string also.
So, there's a type conflict in your use of e1.
type expr = NUM of int
| PLUS of expr * expr
| MINUS of expr * expr
let rec calc expr1 =
match expr1 with
| NUM i -> NUM i
| PLUS (lexpr1, rexpr1) ->
(match lexpr1, rexpr1 with
| (*(NUM li1,NUM ri1) -> NUM li1+ri1*)
| (lexpr1', rexpr1') -> PLUS (calc lexpr1', calc rexpr1'))
It says
Error: This expression has type expr but an expression was expected of type int
I don't know why errors keep coming out
Ocaml in the line
NUM li1+ri1
first creates a NUM and then tries to add ri1. But since + operator applies only on ints and not at expr and int, it throws an error.
To fix this add ints first:
NUM (li1+ri1)
I need to convert an arithmetic sequence that uses
this type:
type expr =
VarX
| VarY
| Sine of expr
| Cosine of expr
| Average of expr * expr
| Times of expr * expr
| Thresh of expr * expr * expr * expr
here are the definitions for all the things in it:
e ::= x | y | sin (pi*e) | cos (pi*e) | ((e + e)/2) | e * e | (e<e ? e : e)
need to convert something like this:
exprToString (Thresh(VarX,VarY,VarX,(Times(Sine(VarX),Cosine(Average(VarX,VarY))))));;
to this:
string = "(x<y?x:sin(pi*x)*cos(pi*((x+y)/2)))"
I know I have to do this recursively by matching each expr with its appropriate string but Im not sure where the function begins matching or how to recurse through it. Any help or clues would be appreciated
Here is a simplified version of what you probably want:
type expr =
| VarX
| Sine of expr
let rec exprToString = function
| VarX -> "x"
| Sine e -> "sin(" ^ exprToString e ^ ")"
let () = print_endline (exprToString (Sine (Sine (Sine (Sine VarX)))))
It recurses over the AST nodes and create the string representation of the input by concatenating the string representations of the nodes.
This approach may not work nicely for bigger real world examples since:
String concatenation (^) creates a new string from two, this is slower than using some more appropriate data structure such as Buffer.t
Too many parentheses, ex, (2*(2*(2*2))), not 2*2*2*2. If you want minimize the number of parentheses, your algorithm must be aware of operator precedence and connectivity.