Change Operator Precedence of --> operator
How about overloading the LongRightArrow
with a special rule for Part[...]
as the second argument?
Unprotect[LongRightArrow];
SetAttributes[LongRightArrow, HoldRest]
LongRightArrow[obj_, property_] := obj[ToString[property]];
LongRightArrow[obj_, Part[property_, partspec__]] :=
Part[LongRightArrow[obj, property], partspec];
Protect[LongRightArrow];
obj = <|"a" -> {2, 3}, "b" -> 5|>
obj⟶a
obj⟶a[[1]]
<|"a" -> {2, 3}, "b" -> 5|> {2, 3} 2
Chip Hurst was quicker than I to show the generalization
LongRightArrow[obj_, head_[f_, args__]] := head[LongRightArrow[obj, f], args]
So I'll just take one more step to handle unary postfix operators, such as !
(Factorial
). Trivial by replacing args__
with args___
:
LongRightArrow[obj_, head_[f_, args___]] := head[LongRightArrow[obj, f], args]
Now
obj⟶a!
{2, 6}
EDIT
Re the comment:
obj⟶a⟶b
is equivalent to
LongRightArrow[obj, a, b]
while the desired behavior is
LongRightArrow[LongRightArrow[obj, a], b]
Well, obviously, that's exactly what we should tell Mathematica, it can't guess that for us.
LongRightArrow[obj_, a_, b__] := LongRightArrow[LongRightArrow[obj, a], b]
obj⟶a⟶b⟶b⟶b⟶b⟶b
(((((obj⟶a)⟶b)⟶b)⟶b)⟶b)⟶b
You could give LongRightArrow
a HoldRest
attribute and manipulate the right hand side.
Perhaps something like:
SetAttributes[LongRightArrow, HoldRest]
LongRightArrow[obj_, head_[f_, args__]] := head[LongRightArrow[obj, f], args]
LongRightArrow[obj_, f_] := obj[ToString[f]]
Test:
obj⟶a
{2, 3}
obj⟶a[[1]]
2
obj⟶a^2
{4, 9}
The precedence of LongRightArrow is predetermined as shown in the operator table. You can attempt to circumvent the problem as other answers show but these do not change the binding power of the operator itself.
As you can see from the table Part
has especially high binding power. What you want therefore goes against the design of Mathematica in some way; one would expect obj⟶(a[[1]])
rather than (obj⟶a)[[1]]
.
If you want to supersede Part
you might consider something with natively higher binding power though there aren't many choices; Overscript
is one:
Overscript[obj_, property_] := obj[ToString[property]];
Now entered using Ctrl+7:
Manually parenthesizing i.e. actually writing (obj⟶a)[[1]]
is another option:
(obj⟶a)[[1]]
2
Note: you do not need to Unprotect
Overscript
or LongRightArrow
as these operators are intended for use.