OCaml literal negative number? - syntax

I'm learning. This is something I found strange:
let test_treeways x = match x with
| _ when x < 0 -> -1
| _ when x > 0 -> 1
| _ -> 0;;
If I then call it like this:
test_threeways -10;;
I will get type mismatch error (because, as far as I understand, it interprets unary minus as if it was partial function application, so it considers the type of the expression to be int -> int. However, this:
test_threeways (-10);;
acts as expected (though this actually calculates the value, as I could understand, it doesn't pass a constant "minus ten" to the function.
So, how do you write constant negative numbers in OCaml?

You need to enclose it in order to avoid parsing amiguity. "test_threeways -10" could also mean: substract 10 from test_threeways.
And there is no function application involved. Just redefine the unary minus, to see the difference:
#let (~-) = (+) 2 ;; (* See documentation of pervarsives *)
val ( ~- ) : int -> int = <fun>
# let t = -2 ;;
val t : int = -2 (* no function application, constant negative number *)
# -t ;;
- : int = 0 (* function application *)

You can use ~- and ~-. directly (as hinted in the other answer), they are both explicitly prefix operators so parsing them is not ambiguous.
However I prefer using parentheses.

Related

How to perform several operations under the same condition?

I want to negate the chosen element of the matrix along with its adjacent elements.
My question is how do I make these multiple expressions happen without '&&'. I don't know the syntax very well.
I am getting-
Error: This expression has type unit but an expression was expected of type bool
let matrix2 =[|[|true;true;false;false|];
[|false;false;true;true|];
[|true;false;true;false|];
[|true;false;false;true|]|];;
let flip_matrix matrix a b=
let n=Array.length matrix in
for i=1 to n do
let n1=Array.length matrix in
for j=1 to n1 do
if i=a && j=b
then
matrix.(i).(j)<- not matrix.(i).(j)&&matrix.(i+1).(j+1)<- not matrix.(i+1).(j+1)&&matrix.(i-1).(j-1)<- not matrix.(i-1).(j-1)
done;
done;
matrix;;
flip_matrix matrix2 1 2;;
The sequencing operator ; is used to chain together several expressions,
<exp1>; <exp2>
means evaluate <exp1> first, then evaluate <exp2>, example:
print_endline "Hello!"; print_endline "World."
Note that ; works only for expressions that return a value of type unit, i.e., that are evaluated only for their side-effects and do not produce any useful values.
When you need to chain several expression that produce useful values, you need to bound those values to some variables, and have to use the let <v> = <exp1> in <exp2>. This expression will evaluate <exp1> and bound it to the variable <v> that becomes available for expression <exp2>, which is evaluated after that. Example,
let message = "hello", ^ ", world" in
print_endline message
As you can see, the <exp1>; <exp2> is just a short-hand notation for,
let () = <exp1> in <exp2>
Also, note that could be a let .. in .. expression itself, so that you can chain an arbitrary number of expressions in OCaml,
let x1 = f1 y1 in
let x2 = f2 y2 in
...
let xN = fN yN in
final_result
Now, we're ready for conditional expressions such as if. It would be natural to assume that
if x > 0 then print_endline "Hello"; print_endline "World"
Would print
Hello
World
If x is greater than zero. But that is wrong! As a I described recent in this answer, the if expression has higher precedence (priority) than ;, so in fact the OCaml parser splits this into two expressions:
(if x > 0 then print_endline "Hello"); print_endline "World"
So that at the end only one of the expressions is under condition. As always in such precedence problems the solution is to use parentheses (or begin/end, which is the same), e.g.,
if x > 0 then (print_endline "Hello"; print_endline "World")
You can also use the more generic let .. in .. if you would like, it works without any extra parentheses, e.g.,
if x > 0 then
let () = print_endline "Hello" in
print_endline "World"
albeit a little bit ugly :)
Mutating assignment of an array evaluates to the unit:
utop # let arr = Array.make 10 0;;
val arr : int array = [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0|]
utop # arr.(0) <- 1;;
- : unit = ()
In this line:
matrix.(i).(j)<- not matrix.(i).(j)&&matrix.(i+1).(j+1)<- not matrix.(i+1).(j+1)&&matrix.(i-1).(j-1)<- not matrix.(i-1).(j-1)
You are using && to conjoin a boolean value with the result of evaluating matrix.(i+1).(j+1) <- ..., and that latter expression with be the unit. Of course && only works to conjoin too boolean values.
I think this should do it:
let matrix33 = [|[|true;true;false;false|];
[|false;false;true;true|];
[|true;false;true;false|];
[|true;false;false;true|]|];;
let flip_matrix matrix a b=
let n=Array.length matrix in
for i=1 to n do
let n1=Array.length matrix in
for j=1 to n1 do
if i=a && j=b
then begin
matrix.(i).(j)<- not matrix.(i).(j);
matrix.(i+1).(j)<- not matrix.(i+1).(j);
matrix.(i).(j+1)<- not matrix.(i).(j+1);
matrix.(i).(j-1)<- not matrix.(i).(j-1);
matrix.(i-1).(j)<- not matrix.(i-1).(j);
end;
done;
done;
matrix;;
flip_matrix matrix33 1 1 ;;```

how to do this without "match ... with"

For a better understanding, I try to rewrite this code without "... with" but I struggle:
let rec blast list =
list with
| x :: y :: [] -> x
| hd :: tl -> blast tl
| _ -> fail "not enough";;
Any ideas? Thanks!
Sure we could "manually" try to match each pattern.
The first applies when there is exactly 2 elements, the second when there is more than 1 (but not 2) and the third in all other cases (0 elements).
The second case can be folded into the last case (As when there is 1 element, the recursive call just fails).
So now we have 3 cases: exactly 2, more than 2 and less than 2.
Perfect for List.compare_length_with: 'a list -> int -> int:
let rec beforelast list =
let cmp = List.compare_length_with list 2 in
if cmp = 0 then (* Exactly 2 elements *)
List.hd list
else if cmp > 0 then (* More than 2 elements *)
beforelast (List.tl list)
else (* 1 or 0 elements *)
failwith "not enough"
Though note that you are still pattern matching under the hood, because that's what OCaml data types are made for. For example, List.hd might be implemented like:
let hd = function
| head :: _ -> head
| [] -> raise (Failure "hd")
So the match ... with way should be the way that leads to a better understanding.

"Variable ... must occur on both sides of this | pattern"

As I was typing up some code in OCaml, I wanted to match two cases at once (since the function I'm writing is commutative):
type something =
| Two of int * int
| One of int
let my_function p q =
match p, q with
| Two (_, _) as two, One (x)
| One (x), Two (_, _) as two -> (* some value *)
| _ -> (* some other value *)
;;
I'm getting the following error:
Error: Variable two must occur on both sides of this | pattern
The problem doesn't occur when I remove the as statement, but I need it for the logic purposes. Why can't I do it like this? Will I have to resort to rewriting the logic twice?
as has lower precedence than ,. Hence you should put parenthesis around Two (_,_) as two.

Is it possible to debug pattern matching in a Haskell function?

I have defined a type
data Expr =
Const Double
| Add Expr Expr
| Sub Expr Expr
and declared it as an instance of Eq typeclass:
instance Eq Expr where
(Add (Const a1) (Const a2)) == Const b = a1+a2 == b
(Add (Const a1) (Const a2)) == (Add (Const b1) (Const b2)) = a1+a2 == b1 + b2
Of course, the evaluation of the expression Sub (Const 1) (Const 1) == Const 0 will fail. How can I debug at runtime the pattern matching process to spot that it's failing? I would like to see how Haskell takes the arguments of == and walks through the patterns. Is it possible at all?
edit: providing a real answer to the question...
I find the easiest way to see what patterns are matching is to add trace statements, like so:
import Debug.Trace
instance Eq Expr where
(Add (Const a1) (Const a2)) == Const b = trace "Expr Eq pat 1" $ a1+a2 == b
(Add (Const a1) (Const a2)) == (Add (Const b1) (Const b2)) = trace "Expr Eq pat 2" $ a1+a2 == b1 + b2
-- catch any unmatched patterns
l == r = error $ "Expr Eq failed pattern match. \n l: " ++ show l ++ "\n r: " ++ show r
If you don't include a final statement to catch any otherwise unmatched patterns, you'll get a runtime exception, but I find it's more useful to see what data you're getting. Then it's usually simple to see why it doesn't match the previous patterns.
Of course you don't want to leave this in production code. I only insert traces as necessary then remove them when I've finished. You could also use CPP to leave them out of production builds.
I also want to say that I think pattern matching is the wrong way to go about this. You'll end up with a combinatorial explosion in the number of patterns, which quickly grows unmanageable. If you want to make a Float instance for Expr for example, you'll need several more primitive constructors.
Instead, you presumably have an interpreter function interpret :: Expr -> Double, or at least could write one. Then you can define
instance Eq Expr where
l == r = interpret l == interpret r
By pattern matching, you're essentially re-writing your interpret function in the Eq instance. If you want to make an Ord instance, you'll end up re-writing the interpret function yet again.
If you wish to get some examples on how the matching may fail, you could have a look at QuickCheck. There's an example on the manual (the size of test data) about generating and testing recursive data types that seems to perfectly suit your needs.
While the -Wall flag gives you a list of patterns non matched, a run of QuickCheck gives you examples of input data that lead your given proposition to failure.
For example, if I write a generator for your Expr and I give in input to quickCheck a proposition prop_expr_eq :: Expr -> Bool that checks if an Expr is equal to itself, I obtain very quickly Const 0.0 as a first example of non-matching input.
import Test.QuickCheck
import Control.Monad
data Expr =
Const Double
| Add Expr Expr
| Sub Expr Expr
deriving (Show)
instance Eq Expr where
(Add (Const a1) (Const a2)) == Const b = a1+a2 == b
(Add (Const a1) (Const a2)) == (Add (Const b1) (Const b2)) = a1+a2 == b1 + b2
instance Arbitrary Expr where
arbitrary = sized expr'
where
expr' 0 = liftM Const arbitrary
expr' n | n > 0 =
let subexpr = expr' (n `div` 2)
in oneof [liftM Const arbitrary,
liftM2 Add subexpr subexpr,
liftM2 Sub subexpr subexpr]
prop_expr_eq :: Expr -> Bool
prop_expr_eq e = e == e
As you see, running the test gives you a counterexample to prove that your equality test is wrong. I know this may be a little bit an overkill, but the advantage if you write things good is that you also get unit tests for your code that look at arbitrary properties, not only pattern matching exhaustiveness.
*Main> quickCheck prop_expr_eq
*** Failed! Exception: 'test.hs:(11,5)-(12,81): Non-exhaustive patterns in function ==' (after 1 test):
Const 0.0
PS: Another good reading about unit testing with QuickCheck is in the free book real world haskell.
You can break your complex pattern into simpler patterns and use trace to see what's going on. Something like this:
instance Eq Expr where
x1 == x2 | trace ("Top level: " ++ show (x, y1)) True,
Add x11 x12 <- x1,
trace ("First argument Add: " ++ show (x11, x12)) True,
Const a1 <- x11,
trace ("Matched first Const: " ++ show a1) True,
Const a2 <- x12,
trace ("Matched second Const: " ++ show a2) True,
Const b <- x2
trace ("Second argument Const: " ++ show b) True
= a1+a2 == b
It's a bit desperate, but desperate times calls for desperate measures. :)
As you get used to Haskell you rarely, if ever, need to do this.

Extending Immutable types (or: fast cache for immutable types) in OCaml

I have a recursive immutable data structure in ocaml which can be simplified to something like this:
type expr =
{
eexpr : expr_expr;
some_other_complex_field : a_complex_type;
}
and expr_expr =
| TInt of int
| TSum of (expr * expr)
| TMul of (expr * expr)
It's an AST, and sometimes it gets pretty complex (it's very deep).
there is a recursive function that evaluates an expression. For example, let's say,
let rec result expr =
match expr.eexpr with
| TInt i -> i
| TSum (e1, e2) -> result e1 + result e2
| TMul (e1, e2) -> result e1 * result e2
Now suppose I am mapping an expression to another expression, and I need to constantly check the result of an expr, sometimes more than once for the same expr, and sometimes for expressions that were recently mapped by using the pattern
{ someExpr with eexpr = TSum(someExpr, otherExpr) }
Now, the result function is very lightweight, but running it many times for a deep AST will not be very optimized. I know I could cache the value using a Hashtbl, but AFAIK the Hashtbl will only do structural equality, so it will need to traverse my long AST anyway.
I know the best option would be to include a probably immutable "result" field in the expr type. But I can't.
So is there any way in Ocaml to cache a value to an immutable type, so I don't have to calculate it eagerly every time I need it ?
Thanks!
Hash-cons the values of expr_expr. By doing this structurally equal values in your program will share exactly the same memory representation and you can substitute structural equality (=) by physical equality (==).
This paper should get you quickly started on hash-consing in OCaml.
You can use the functorial interface to control the kind of equality used by the hash table. I believe the semantics of (==) are legitimate for your purposes; i.e., if A == B then f A = f B for any pure function f. So you can cache the results of f A. Then if you find a B that's physically equal to A, the cached value is correct for B.
The downside of using (==) for hashing is that the hash function will send all structurally equal objects to the same hash bucket, where they will be treated as distinct objects. If you have a lot of structurally equal objects in the table, you get no benefit from the hashing. The behavior degenerates to a linear search.
You can't define the hash function to work with physical addresses, because the physical addresses can be changed at any time by the garbage collector.
However, if you know your table will only contain relatively few large-ish values, using physical equality might work for you.
I think you can merge the two ideas above : use hash-consing-like techniques to get the hash of the "pure expression" part of your data, and use this hash as key in the memoization table for the eval function.
Of course this only works when your eval function indeed only depends on the "pure expression" part of the function, as in the example you gave. I believe that is a relatively general case, at least if you restrict yourself to storing the successful evaluations (that won't, for example, return an error including some location information).
Edit: a small proof of concept:
type 'a _expr =
| Int of int
| Add of 'a * 'a
(* a constructor to avoid needing -rectypes *)
type pure_expr = Pure of pure_expr _expr
type loc = int
type loc_expr = {
loc : loc;
expr : loc_expr _expr;
pure : pure_expr (* or any hash_consing of it for efficiency *)
}
(* this is where you could hash-cons *)
let pure x = Pure x
let int loc n =
{ loc; expr = Int n; pure = pure (Int n) }
let add loc a b =
{ loc; expr = Add (a, b); pure = pure (Add(a.pure, b.pure)) }
let eval =
let cache = Hashtbl.create 251 in
let rec eval term =
(* for debug and checking memoization *)
Printf.printf "log: %d\n" term.loc;
try Hashtbl.find cache term.pure with Not_found ->
let result =
match term.expr with
| Int n -> n
| Add(a, b) -> eval a + eval b in
Hashtbl.add cache term.pure result;
result
in eval
let test = add 3 (int 1 1) (int 2 2)
# eval test;;
log: 3
log: 2
log: 1
- : int = 3
# eval test;;
log: 3
- : int = 3

Resources