Skip to content

Commit

Permalink
feat(#60): implement mapNullable in Maybe monad
Browse files Browse the repository at this point in the history
  • Loading branch information
JSMonk committed Jul 30, 2023
1 parent 3fbd161 commit 68d3625
Show file tree
Hide file tree
Showing 5 changed files with 9,947 additions and 718 deletions.
38 changes: 37 additions & 1 deletion maybe/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ const v2 = from<2>(2); // Maybe<2>.Just
#### `fromNullable`

```typescript
function fromNullable<T>(value: T): Maybe<Exclude<T, null | undefined>>;
function fromNullable<T>(value: T): Maybe<NonNullable<T>>;
```

- Returns `Maybe` with `Just` state which contain value with `T` type if value is not null or undefined and `None` otherwise.
Expand Down Expand Up @@ -266,6 +266,42 @@ const newVal1 = v1.map(a => a.toString()); // Maybe<string>.Just with value "2"
const newVal2 = v2.map(a => a.toString()); // Maybe<string>.None without value
```

#### `Maybe#mapNullable`

```typescript
function mapNullable<Val, NewVal>(fn: (val: Val) => (NewVal | null | undefined)): Maybe<NonNullable<NewVal>>;
```

- Returns mapped by `fn` function value wrapped by `Maybe` if `Maybe` is `Just` and the returned value is not `null` or `undefined` otherwise `None`
Example:

```typescript
const v1 = just(2);
const v2 = none<number>();

const newVal1 = v1.mapNullable(a => a.toString()); // Maybe<string>.Just with value "2"
const newVal2 = v2.mapNullable(a => a.toString()); // Maybe<string>.None without value
const newVal3 = v2.mapNullable<string | null>(a => null); // Maybe<string>.None without value
const newVal4 = v2.mapNullable<string | void>(a => undefined); // Maybe<string>.None without value
```

#### `Maybe#mapNullable`

```typescript
function map<Val, NewVal>(fn: (val: Val) => NewVal): Maybe<NewVal>;
```

- Returns mapped by `fn` function value wrapped by `Maybe` if `Maybe` is `Just` otherwise `None`
Example:

```typescript
const v1 = just(2);
const v2 = none<number>();

const newVal1 = v1.map(a => a.toString()); // Maybe<string>.Just with value "2"
const newVal2 = v2.map(a => a.toString()); // Maybe<string>.None without value
```

##### `Maybe#asyncMap`

```typescript
Expand Down
16 changes: 12 additions & 4 deletions maybe/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,8 @@ export default class MaybeConstructor<T, S extends MaybeState = MaybeState>
return MaybeConstructor.just(v);
}

static fromNullable<T>(v: T): Maybe<Exclude<T, null | undefined>> {
return v !== null && v !== undefined
? MaybeConstructor.just(v as Exclude<T, null | undefined>)
: MaybeConstructor.none<Exclude<T, null | undefined>>();
static fromNullable<T>(v: T): Maybe<NonNullable<T>> {
return v != null ? MaybeConstructor.just(v as NonNullable<T>) : MaybeConstructor.none<NonNullable<T>>();
}

private static _noneInstance: MaybeConstructor<any, MaybeState.None>;
Expand Down Expand Up @@ -120,6 +118,16 @@ export default class MaybeConstructor<T, S extends MaybeState = MaybeState>
return MaybeConstructor.none<V>();
}

mapNullable<V>(f: (r: T) => V | null | undefined): Maybe<NonNullable<V>> {
if (this.isJust()) {
const result = f(this.value);
if (result == null) return MaybeConstructor.none();
return MaybeConstructor.just(result);
}

return MaybeConstructor.none();
}

asyncMap<V>(f: (r: T) => Promise<V>): Promise<Maybe<V>> {
if (this.isJust()) {
return f(this.value).then(MaybeConstructor.just);
Expand Down
Loading

0 comments on commit 68d3625

Please sign in to comment.