smlpolyml

Standard ML export operator from structure as infix


I would like to declare an infix operator within a structure a for use outside the structure. But I cannot seem to get the "infixness" to be recognized outside the structure even when the structure has been opened. Here is an example using Poly/ML:

> structure A = struct infix 6 ++ fun a ++ b = a + b end;
structure A: sig val ++: int * int -> int end
> 1 A.++ 2;
poly: : error: Type error in function application.
   Function: 1 : int
   Argument: A.++ : int * int -> int
   Reason: Value being applied does not have a function type
Found near 1 A.++ 2
Static Errors
> let open A in 1 ++ 2 end;
poly: : error: Type error in function application.
   Function: 1 : int
   Argument: ++ : int * int -> int
   Reason: Value being applied does not have a function type
Found near let open A in 1 ++ 2 end
Static Errors

Is this a limitation of Standard ML?


Solution

  • Yes, this is not supported by Standard ML. You'll have to re-declare the fixity and, optionally, the precedence every time you open that structure. One way to get around it is to declare the fixity globally, i.e., outside any structure, but this isn't well supported with separate compilation and it isn't very modular either. You can read more about it and a possible workaround on the MLton's InfixingOperators page.

    For my own projects, I've defined a shortcut in my text editor that will expand into both an open declaration as well as a fixity one.

    Also, as a personal style guide, I'm not declaring the precedence. If I need to mix multiple infix operators into the same expression, I'll rather use parentheses explicitly. Eye-parsing an identifier as infix is easy, parsing the precedence is not.