Unary minus and floating point number in OCaml

I wanted to have a vector of complex numbers in my program, so I wrote the following:

[|pt 0. 0.; pt -4. 1.; pt -7. -2.; pt 4. 5.; pt 1. 1.|] 

Here pt is a function of type float -> float -> Complex.t . But ocaml refused to compile this statement:

 Characters 12-14: [|pt 0. 0.; pt -4. 1.; pt -7. -2.; pt 4. 5.; pt 1. 1.|];; ^^ Error: This expression has type float -> float -> Complex.t but an expression was expected of type int 

What I wanted to do here (obviously) includes a complex number, the real part of which is -4, whose imaginary part is 1. But ocaml considered what I intended to be a unary minus, as a function of type int -> int ->int .

What should I write to do what I wanted?

+4
source share
1 answer

This is how I think this happens (after reading documents and experiments). Indeed, there are four completely different operators:

 - Integer subtraction int -> int -> int -. Floating subtraction float -> float -> float ~- Integer unary negation int -> int ~-. Floating unary negation float -> float 

If everyone used these operators, everything would be clear, but, unfortunately, this is also a rather clumsy notation. In my experience, the operators are ~- and ~-. rarely used. The OCaml grammar is specified so that you can use the subtraction operators as unary negation operators, as in many other languages. If you do this, you will often have to use extra parentheses. If you want to use certain unary operators, you do not need parentheses.

Ie, you can write (as in the edited answer):

 [|pt 0. 0.; pt ~-.4. 1.; pt ~-.7. ~-.2.; pt 4. 5.; pt 1. 1.|] 

Or you can write:

 [|pt 0. 0.; pt (-.4.) 1.; pt (-.7.) (-.2.); pt 4. 5.; pt 1. 1.|] 

There is also one additional confusing factor, which is that lexer OCaml is specified so that you can use the integer subtraction operator for unary negation when using it with a floating constant. Again, this makes the notation more like other languages. Since it is mainly a binary operator, you also need parentheses.

This means that you can write:

 [|pt 0. 0.; pt (-4.) 1.; pt (-7.) (-2.); pt 4. 5.; pt 1. 1.|] 

This notation only works for negative floating constants. The other two entries work for any expression that you can deny.

 # (-) ;; - : int -> int -> int = <fun> # (-.) ;; - : float -> float -> float = <fun> # (~-) ;; - : int -> int = <fun> # (~-.) ;; - : float -> float = <fun> # let fx = x +. 2.0;; val f : float -> float = <fun> # f ~-.5.;; - : float = -3. # f -.5.;; Characters 0-1: f -.5.;; ^ Error: This expression has type float -> float but an expression was expected of type float # f (-.5.);; - : float = -3. # f -5.;; ^ Error: This expression has type float -> float but an expression was expected of type int # f (-5.);; - : float = -3. 
+11
source

Source: https://habr.com/ru/post/1392643/


All Articles