Why these arguments inferred to have a unit type?
Asked Answered
S

1

7

I deliberately added x to the end of this function

let myMax x y =
  if x > y then x else y
  x

I was expecting that x and y arguments are still of ‘a type, but I get this signature instead:

myMax : x:unit -> y:unit -> unit

Why these arguments inferred to have a unit type?

Edit: Thank you @gilles for the answer. Consider these two functions:

let foo x y =
  0              // warning
  x
val foo : x:'a -> y:'b -> 'a

let foo2 x y =
  if x > y then x else y   // no warning
  x
val foo2 : x:unit -> y:unit -> unit

What makes the two signatures different? Seems like in the second function the compiler interpret the result of the comparison –either x or y- as unit

Schrecklichkeit answered 7/5, 2016 at 21:36 Comment(0)
P
7

Let's write a simpler example:

> fun x -> x; 0;;          
val it : unit -> int = <fun:clo@5>

In a compound expression, the expression before the semicolon/newline operator must have unit type. If you want to use an expression with a “real” value (i.e. anything of a type other than unit), you need to ignore it explicitly, or bind it to a variable-less pattern. The compiler reminds you if the expression's type can't be unified with unit:

> fun x -> 0; x;;

  fun x -> 0; x;;
  ---------^

stdin(7,10): warning FS0020: This expression should have type 'unit', but has type 'int'. 
Use 'ignore' to discard the result of the expression, 
or 'let' to bind the result to a name.
val it : x:'a -> 'a = <fun:clo@7-1>

It would be possible to have a typing rule that allows any type before ; — the value is ignored, after all, so its type doesn't matter — but that would make it easy to accidentally discard a return value that matters. So if you want to ignore the value, do so explicitly:

let myMax x y =
  ignore (if x > y then x else y)
  x

or

let myMax x y =
  let _ = if x > y then x else y
  x
Prostitute answered 7/5, 2016 at 21:55 Comment(1)
I would also add that if you find yourself using ignore, chances are, you're doing something wrong. This particular example is not an exception either: the if-then expression doesn't make any sense, because its return value is thrown away and it doesn't produce any side effects.Ozonide

© 2022 - 2024 — McMap. All rights reserved.