You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+36-3Lines changed: 36 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -75,6 +75,7 @@ The following is a partial exploration of what I've been imagining for awhile. T
75
75
*[Monads](#monads)
76
76
-[The Monad Laws](#the-monad-laws)
77
77
-[Do Syntax](#do-syntax)
78
+
-[Monadic Function Returns](#monadic-function-returns)
78
79
*[Type Annotations](#type-annotations)
79
80
80
81
### Imports
@@ -1192,7 +1193,7 @@ defn add(x: 0, y) ^x + y;
1192
1193
Function recursion is supported:
1193
1194
1194
1195
```java
1195
-
defn factorial(v) ?[v ?<=1]:1 {
1196
+
defn factorial(v) ![v ?>1]:1 {
1196
1197
^v * factorial(v -1);
1197
1198
}
1198
1199
@@ -1202,8 +1203,8 @@ factorial(5); // 120
1202
1203
Tail-calls (recursive or not) are automatically optimized by the **Foi** compiler to save call-stack resources:
1203
1204
1204
1205
```java
1205
-
defn factorial(v,tot:1) ?[v ?<=1]: tot {
1206
-
^factorial(v -1,tot * v)
1206
+
defn factorial(v,tot:1) ![v ?>1]: tot {
1207
+
^factorial(v -1,tot * v);
1207
1208
}
1208
1209
1209
1210
factorial(5); // 120
@@ -1748,6 +1749,38 @@ def m: Id @ {
1748
1749
1749
1750
Inside the `@ { }` do-block, a unary/prefixed `@` expression implicitly chains a monad to the current block's monad context, resulting in the underlying value.
1750
1751
1752
+
#### MonadicFunctionReturns
1753
+
1754
+
A function's return value can be explicitly expressed monadically:
1755
+
1756
+
```java
1757
+
defn incM(v) ^(Id @ v + 1);
1758
+
1759
+
incM(3); // Id{4}
1760
+
```
1761
+
1762
+
Non-monadic-returning functions can also be composed with the intended unit constructor:
1763
+
1764
+
```java
1765
+
defn inc(v) ^v + 1;
1766
+
def incM: inc +> Id @;
1767
+
1768
+
incM(3); // Id{4}
1769
+
```
1770
+
1771
+
That approach is often useful if the non-monadic-returning function is already independently defined, so effectively a monad is just being *wrapped* around the function's return value.
1772
+
1773
+
Monadic function returns can also be integrated directly into a function's logic:
1774
+
1775
+
```java
1776
+
defn factorialM(v,tot: Id @ 1) ![v ?> 1]: tot {
1777
+
tot := tot ~map (t) { t * v; };
1778
+
^factorialM(v - 1,tot);
1779
+
}
1780
+
1781
+
factorialM(5); // Id{120}
1782
+
```
1783
+
1751
1784
### Type Annotations
1752
1785
1753
1786
Type annotations in **Foi** are applied to values/expressions (not to variables, etc). These are optional, as **Foi** uses type inference wherever possible. But applying them can often improve the performance optimizations the **Foi** compiler can produce. A type annotation always begins with the `as` keyword:
0 commit comments