Skip to content

Commit 31c209d

Browse files
committed
README: adding section 'monadic function returns'
1 parent 2c79013 commit 31c209d

File tree

1 file changed

+36
-3
lines changed

1 file changed

+36
-3
lines changed

README.md

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ The following is a partial exploration of what I've been imagining for awhile. T
7575
* [Monads](#monads)
7676
- [The Monad Laws](#the-monad-laws)
7777
- [Do Syntax](#do-syntax)
78+
- [Monadic Function Returns](#monadic-function-returns)
7879
* [Type Annotations](#type-annotations)
7980

8081
### Imports
@@ -1192,7 +1193,7 @@ defn add(x: 0, y) ^x + y;
11921193
Function recursion is supported:
11931194

11941195
```java
1195-
defn factorial(v) ?[v ?<= 1]: 1 {
1196+
defn factorial(v) ![v ?> 1]: 1 {
11961197
^v * factorial(v - 1);
11971198
}
11981199

@@ -1202,8 +1203,8 @@ factorial(5); // 120
12021203
Tail-calls (recursive or not) are automatically optimized by the **Foi** compiler to save call-stack resources:
12031204

12041205
```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);
12071208
}
12081209

12091210
factorial(5); // 120
@@ -1748,6 +1749,38 @@ def m: Id @ {
17481749
17491750
Inside the `@ { }` do-block, a unary/prefixed `@` expression implicitly chains a monad to the current block's monad context, resulting in the underlying value.
17501751

1752+
#### Monadic Function Returns
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+
17511784
### Type Annotations
17521785
17531786
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

Comments
 (0)