takže jestli to chápu správně, tak si nemůžu udělat operátor "mod' apod.? Jen něco s "paznaky"?
IMHO jestli si pamatuju dobře, tak to původní ML umožňoval přes "infix" že?
Ajo ted jsem si zkusil a zrovna jak na potvoru mod jde :)
let foo x y = x + y;;
let ( mod ) = foo;;
30 mod 40;;
Myslel jsem obecne, ale to fakt zda se nejde, OCaml rve. Pockam si na popis F#, tam co jsem se zbezne dival, to zmenili.
Nepříjemné bylo, že ty infix deklarace se nedaly naimportovat z modulů. Takže je člověk musel pokaždé zkopírovat.
Jak radekm napsal, existující operátory je možné předefinovat, ale nové musí být složeny právě jen z těch paznaků :-) Není to ideální, ale na druhou stranu asi OCaml nekandiduje jako náhrada za APL (i když já bych klidně povolil možnost definice i obecnějších operátorů).
Řekl bych, že když se to používá s mírou, tak to může zlepšit čitelnost.
Třeba operátory @@, >>=, |>.
Pak je otázkou, zda to některé knihovny trošku nepřehánějí. Třeba v F# je knihovna Farkle pro parsování, kde gramatiky lze psát
let expression =
let NEG = obj()
let expression = nonterminal "Expression"
expression.SetProductions(
!@ number |> asIs,
!@ expression .>> "+" .>>. expression => (fun x1 x2 -> x1 + x2),
!@ expression .>> "-" .>>. expression => (fun x1 x2 -> x1 - x2),
!@ expression .>> "*" .>>. expression => (fun x1 x2 -> x1 * x2),
!@ expression .>> "/" .>>. expression => (fun x1 x2 -> x1 / x2),
!& "-" .>>. expression |> prec NEG => (fun x -> -x),
!@ expression .>> "^" .>>. expression => (fun x1 x2 -> Math.Pow(x1, x2)),
// We use |> asIs instead of => (fun x -> x).
!& "(" .>>. expression .>> ")" |> asIs
)
let opScope =
OperatorScope(
LeftAssociative("+", "-"),
LeftAssociative("*", "/"),
PrecedenceOnly(NEG),
RightAssociative("^")
)
DesigntimeFarkle.withOperatorScope opScope expression
Cílem je, aby se to podobalo následujícímu zápisu z Bisonu:
%left '-' '+'
%left '*' '/'
%precedence NEG
%right '^'
exp:
NUM
| exp '+' exp { $$ = $1 + $3; }
| exp '-' exp { $$ = $1 - $3; }
| exp '*' exp { $$ = $1 * $3; }
| exp '/' exp { $$ = $1 / $3; }
| '-' exp %prec NEG { $$ = -$2; }
| exp '^' exp { $$ = pow ($1, $3); }
| '(' exp ')' { $$ = $2; }
;