# Going full functional (Haskell style)

I'm trying to define some notation so that Mathematica code would be more functional, similar to Haskell (just for fun): currying, lambdas, infix operator to function conversion, etc.. And I have some questions about it:

• Is it possible to make all Mathematica h_[x1_,x2_,...] functions to work as h[x1][x2][..]?
• Can I distinguish inside Notation box between <+1> and <1+>, how do I check for + there?
• How to define right-associate apply operator with highest precedence ($)? This is what I have so far: << Notation; lapply[x_, y_] := x[y] rapply[x_, y_] := x[y] InfixNotation[ParsedBoxWrapper["\\"], lapply] InfixNotation[ParsedBoxWrapper["$"], rapply]
x_ \ y_ \ z_ := x[y][z]
x_ $y_$ z_ := x[y[z]]

Notation[ParsedBoxWrapper[
RowBox[{
RowBox[{"\[Lambda]", " ", "x__"}], "->",
"y_"}]] \[DoubleLongLeftRightArrow] ParsedBoxWrapper[
RowBox[{"Function", "[",
RowBox[{
RowBox[{"{", "x__", "}"}], ",", "y_"}], "]"}]]]

Notation[ParsedBoxWrapper[
RowBox[{"\[LeftAngleBracket]",
RowBox[{"op_", " ", "x_"}],
"\[RightAngleBracket]"}]] \[DoubleLongLeftRightArrow]
ParsedBoxWrapper[
RowBox[{
RowBox[{"#", "op_", " ", "x_"}], "&"}]]]
RowBox[{"\[LeftAngleBracket]",
RowBox[{"\[Placeholder]", "\[Placeholder]"}],
"\[RightAngleBracket]"}]]]

Notation[ParsedBoxWrapper[
RowBox[{"{",
RowBox[{
RowBox[{"x_", " ", ".."}], " ", "y_"}],
"}"}]] \[DoubleLongLeftRightArrow] ParsedBoxWrapper[
RowBox[{"Range", "[",
RowBox[{"x_", ",", "y_"}], "]"}]]]

filter[f_][x_List] := Select[x, f]
map[f_][x__List] := Map[f, x]

filter\PrimeQ $map\\[LeftAngleBracket]-1\[RightAngleBracket]$ map\ \
(\[Lambda] x -> 2^x)\ {1 .. 100}


EDIT: Also did some kinda lazy lists, soon it will be haskell inside Mathematica :)

SetAttributes[list, HoldAll]
list[h_, l_][x_] := list[h, l[x]]
list[x_] := list[x, list]

map[f_][list] := list
map[f_][list[x_, xs_]] := list[f[x], map[f][xs]]

take[0][_] := list
take[_][list] := list
take[n_Integer][list[x_, xs_]] := list[x, take[n - 1][xs]]

range[n_Integer] := range[1, n]
range[m_, n_] := list[m, range[m + 1, n]]
range[n_, n_] := list[n, list]

show[list] := "[]"
show[list[x_, l_]] := ToString[x] <> "," <> show[l]

## Low level Box forms

I cannot recall the limits of the Notation package in this regard, but you can determine how Mathematica parses an expression, and therefore what is accessible with $PreRead or CellEvaluationFunction, using a method from John Fultz (learned here): parseString[s_String, prep : (True | False) : True] := FrontEndExecute[UndocumentedTestFEParserPacket[s, prep]]  The default True should be used in our application as this is the form that will be seen by $PreRead, etc. Testing your example expressions:

parseString @ "<+1>"
parseString @ "<1+>"

{BoxData[RowBox[{"<", RowBox[{"+", "1"}], ">"}]], StandardForm}

{BoxData[RowBox[{"<", RowBox[{"1", "+"}], ">"}]], StandardForm}


One can see that in isolation these parse to distinct forms.

## New operators

I described how to create a new operator in: How can one define an infix operator with an arbitrary unicode character?

And a more mild example in: Prefix operator with low precedence

I recommend that you do not attempt to redefine the $ symbol itself as your operator as this is extensively used internally in temporary symbol names (Module, Unique, etc.). - Very cool and simple "currying" definition. You can add something like MakeBoxes[Function[arg_, f[a__, arg_], HoldAll], StandardForm] := RowBox[{"f", "[", Sequence @@ Riffle[{ReleaseHold[ Function[x, ToString[Unevaluated[x]], HoldAll] /@ Hold[a]]}, "]["], "]"}] to make it still look simple as long as it's still gathering parameters. I suspect it could be achieved in a more elegant fashion, but it demonstrate the idea. – jVincent Apr 23 '13 at 12:33 That's how I finally defined haskell operators: rapply[x_] := x rapply[x_, y__] := x[rapply[y]] InfixNotation[ParsedBoxWrapper["|"], rapply] lapply[x_] := x lapply[x__, y_] := lapply[x][y] InfixNotation[ParsedBoxWrapper["\[SmallCircle]"], lapply] InfixNotation[ParsedBoxWrapper["\[CenterDot]"], Composition]  Now$\circ$,$\dot{}{}$and | act exactly like haskell's space, . and$ respectfully. Also if we have only single left application then @ is still helpful and it can be hidden with escape characters :@:.

And beautiful code like $\bf{show\cdot take\ 10\cdot map\ (\lambda\ x\to x{}^{\wedge}2)\cdot range | \infty }$ is possible. There are invisible @'s between take and 10, map and ($\lambda\ x\to x{}^{\wedge}2)$. In haskell the same would look like $\bf{show . take\ 10.map(\backslash x->x{}^{\wedge}2)$[1..]}$. With double left application,$\circ$is necessary:$\bf{map\circ(\lambda\ x\to x+1)\circ \{1,2,3\}}\$

UPDATE: I made this TextCell hack to make partial infix operators:

infix[f_String] := Block[{x,y},Head[ToExpression["x" <> f <> "y"]]]

\[LeftAngleBracket]TextCell[s_][x_]\[RightAngleBracket] := infix[s][#, x] &
\[LeftAngleBracket]x_[TextCell[s_]]\[RightAngleBracket] := infix[s][x, #] &


We again can use invisible @ for application. Aliases can be made with TextCell on the left and on the right within AngleBrackets` to enter them conveniently. Now stuff like <~Mod~10>, <2^>, <^3> also works.

-