Skip to content

Commit ff150e0

Browse files
andy.pattersonandnp
authored andcommitted
docs: add maybeT to documentation
1 parent 4816a7b commit ff150e0

File tree

1 file changed

+85
-1
lines changed

1 file changed

+85
-1
lines changed

README.md

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# MaybeTyped
22

33
[![Build Status](https://travis-ci.org/andnp/MaybeTyped.svg?branch=master)](https://travis-ci.org/andnp/MaybeTyped)
4-
[![Greenkeeper badge](https://badges.greenkeeper.io/andnp/MaybeTyped.svg)](https://greenkeeper.io/)
54
[![codecov](https://codecov.io/gh/andnp/MaybeTyped/branch/master/graph/badge.svg)](https://codecov.io/gh/andnp/MaybeTyped)
65
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
76
[![Known Vulnerabilities](https://snyk.io/test/github/andnp/maybetyped/badge.svg?targetFile=package.json)](https://snyk.io/test/github/andnp/maybetyped?targetFile=package.json)
7+
[![Greenkeeper badge](https://badges.greenkeeper.io/andnp/MaybeTyped.svg)](https://greenkeeper.io/)
88

99
MaybeTyped is a well-typed Maybe (optional) monad written in typescript.
1010

@@ -156,3 +156,87 @@ const nullable = maybe(value).asNullable();
156156

157157
assert(nullable === value);
158158
```
159+
160+
## MaybeT
161+
```typescript
162+
export function apiUserSearch(user: string): MaybeT<Promise<UserData>> {
163+
// if user does not exist, api returns undefined
164+
return maybeT(fetch(`some/uri?user=${user}`).json());
165+
}
166+
167+
const userBirthday = await apiUserSearch('yagami')
168+
.map(user => user.birthday)
169+
.map(date => new Date(date))
170+
.orElse(() => Date.now()); // <- this is probably a bad design choice :P
171+
172+
const userBirthdayPromises = maybeT(['misa misa', 'light', null, 'ryuk'])
173+
.map(apiUserSearch)
174+
.map(maybeUser =>
175+
maybeUser
176+
.map(user => user.birthday)
177+
.map(date => new Date(date))
178+
.orElse(() => Date.now()))
179+
.asNullable();
180+
181+
const userBirthdays = await Promise.all(userBirthdayPromises);
182+
```
183+
184+
## Api
185+
186+
### maybeT
187+
`maybeT` is the constructor for a maybe transform.
188+
Anything with a `map` function can be transformed into a `maybeT`.
189+
Due to the commonality of the use case, support for `thenables` is also added, though be warned that `then` matches `flatMap` semantics, not `map` semantics.
190+
```typescript
191+
const maybeThings = maybeT([1, 2, null, 4, undefined, 6]); // MaybeT<Array<number>>
192+
const maybeLater = maybeT(Promise.resolve('hey')); // MaybeT<Promise<string>>
193+
```
194+
195+
### map
196+
```typescript
197+
const things = maybeT(['1', '2', null, '4']) // MaybeT<Array<string>>
198+
.map(x => parseInt(x)); // MaybeT<Array<number>>
199+
```
200+
201+
### caseOf
202+
```typescript
203+
const things = maybeT([1, 2, null, 4])
204+
.caseOf({
205+
none: () => 4,
206+
some: x => x + 1,
207+
}); // MaybeT<Array<number>> => MaybeT<[2, 3, 4, 5]>
208+
```
209+
210+
### orElse
211+
```typescript
212+
const things = maybeT([1, 2, null, 4])
213+
.orElse(3); // MaybeT<Array<number>> => MaybeT<[1, 2, 3, 4]>
214+
```
215+
216+
### asNullable
217+
```typescript
218+
const things = maybeT([1, 2, null, 4])
219+
.asNullable(); // Array<number> => [1, 2, null, 4]
220+
```
221+
222+
### asType
223+
Because typescript does not have support for higher-kinded-types (HKT), we lose track of which monad-like HKT we are dealing with (`Array` or `Promise` or other).
224+
This means that after most operations the type will become `MaybeT<MonadLike<*>>`.
225+
To cope with this, we provide an `asType` method that will allow us to properly "remember" what type of monad we were originally dealing with.
226+
A little type safety will be lost here, as you could lie and say this is an `Array` instead of a `Promise`, but the constructor that is passed in to this method will confirm the type at runtime.
227+
This method also asks for the contained type, but because we _haven't_ forgotten that, we will be able to check that.
228+
229+
Programmatic examples below should help make this more clear.
230+
```typescript
231+
const a = maybeT(Promise.resolve('hi'))
232+
.asType<Promise<string>>(Promise); // Promise<string> => this is correct
233+
234+
const b = maybeT(Promise.resolve('hey'))
235+
.asType<Array<string>>(Array); // Array<string> => this will throw a runtime err, but not a compile err
236+
237+
const c = maybeT(Promise.resolve('hello'))
238+
.asType<Promise<number>>(Promise); // any => this will throw a compile err, but not runtime
239+
240+
const d = maybeT(Promise.resolve('merp'))
241+
.asType<Promise<string>>(Array); // any => this will throw a compile err and runtime
242+
```

0 commit comments

Comments
 (0)