Abel
Abel

Reputation: 57159

Error: Unexpected infix operator in expression, about a successfully compiled prefix operator

Playing around a little bit with infix operators, I was surprised about the following:

let (>~~~) = function null -> String.Empty | s -> s  // compiles fine, see screenshot
match >~~~ input with .... // error: Unexpected infix operator in expression

val (>~~~) : string -> string)

and:

Unexpected infix operator

Changing the first characters of the prefix operator (to !~~~ for instance) fixes it. That I get an error that the infix operator is unexpected is rather weird. Hovering shows the definition to be string -> string.

I'm not too surprised about the error, F# requires (iirc) that the first character of a prefix operator must itself be one of the predefined prefix operators. But why does it compile just fine, and when I use it, the compiler complains?

Update: the F# compiler seems to know in other cases just fine when I use an invalid character in my operator definition, it says "Invalid operator definition. Prefix operator definitions must use a valid prefix operator name."

Invalid operator definition.

Upvotes: 3

Views: 2092

Answers (1)

Tomas Petricek
Tomas Petricek

Reputation: 243051

The rules for custom operators in F# are quite tight - so even though you can define custom operators, there is a lot of rules about how they will behave and you cannot change those. In particular:

  • Only some operators (mainly those with ! and ~) can be used as prefix operators. With ~ you can also overload unary operators +, -, ~ and ~~, so if you define an operator named ~+., you can then use it as e.g. +. 42.
  • Other operators (including those starting with >) can only be used as infix. You can turn any operator into ordinary function using parentheses, which is why e.g. (+) 1 2 is valid.
  • The ? symbols is special (it is used for dynamic invocation) and cannot appear as the first symbol of a custom operator.

I think the most intuitive way of thinking about this is that custom operators will behave like standard F# operators, but you can add additional symbols after the standard operator name.

Upvotes: 3

Related Questions