enedil
enedil

Reputation: 1645

Type inference rules

I tried to make a function that takes two characters, takes their ASCII value and returns their XOR. Of course, that works:

> let a, b = '#', '%' in (int a) ^^^ (int b);;
val it : int = 6

This however makes a function that takes integers, which is not the case here.

> let xor a b  = (int a) ^^^ (int b);;                        

val xor : a:int -> b:int -> int

As expected, I can't call this function on previous arguments:

> let a, b = '#', '%' in xor a b;;

  let a, b = '#', '%' in xor a b;;
  ---------------------------^

/home/cos/stdin(121,28): error FS0001: This expression was expected to have type
    int    
but here has type
    char    

Why does it happen? How to specify directly the types of arguments?

Upvotes: 3

Views: 93

Answers (1)

nilekirk
nilekirk

Reputation: 2383

This is how:

let xor (a: char) (b: char)  = (int a) ^^^ (int b)

You can also mark it inline to get a generic function

let inline xor a b  = (int a) ^^^ (int b)

This will have the type

val inline xor :
  a: ^a -> b: ^b -> int
    when  ^a : (static member op_Explicit :  ^a -> int) and
          ^b : (static member op_Explicit :  ^b -> int)

and thus work for anything that can be converted to int.

The reason that

let xor a b  = (int a) ^^^ (int b)

is inferred to have type int -> int -> int is that for arithmetic operations, F# infers the type int by default (See language specification, page 13)

Upvotes: 7

Related Questions