An open API service indexing awesome lists of open source software.

https://github.com/aloisdeniel/dart_maybe

No more null check with an dart equivalent of Maybe (Haskel, Elm) / Option (F#).
https://github.com/aloisdeniel/dart_maybe

dart functional maybe option

Last synced: 25 days ago
JSON representation

No more null check with an dart equivalent of Maybe (Haskel, Elm) / Option (F#).

Awesome Lists containing this project

README

          

# maybe

[![Pub](https://img.shields.io/pub/v/maybe.svg)](https://pub.dartlang.org/packages/maybe)

No more null check with an dart equivalent of Maybe (Haskel, Elm) / Option (F#).

## Usage

The key is that you need to call the `some` or `when` to access your potential value so you are forced to check its status before using it.

### `Maybe.nothing` : creating an optional item that is empty

```dart
final maybe = Maybe.nothing();
```

### `Maybe.some` : creating an optional item with a value

```dart
final maybe = Maybe.some("hello world");
```

```dart
final isNothing = Maybe.some(null); // By default `some` with a null value is converted to `nothing`
final isNotNothing = Maybe.some(null, nullable: true);
```

### `some` : extracting some value

```dart
final maybe = Maybe.some("hello world");
final value = some(maybe, "default"); // == "hello world"
```

```dart
final maybe = Maybe.nothing();
final value = some(maybe, "default"); // == "default"
```

### `isNothing` : testing if some value

```dart
final maybe = Maybe.some("hello world");
final value = isNothing(maybe); // false
```

```dart
final maybe = Maybe.nothing();
final value = isNothing(maybe); // true
```

### `when` : triggering an action

```dart
var maybe = Maybe.some("hello world");
when(maybe, some: (v) {
print(v); // "hello world"
});

// Defining nothing
maybe = Maybe.nothing();
when(maybe, some: (v) {
print(v); // not called!
});

// You can add a default value when nothing
maybe = Maybe.some(null);
when(maybe, some: (v) {
print(v); // "hello world"
},
defaultValue: () => "hello world");
```

### `mapSome` : converts a value type to another

```dart
var maybe = Maybe.some("hello world");
var converted = mapSome(maybe, (v) => v.length);
var value = some(converted,0); // == 11
```

```dart
var maybe = Maybe.nothing();
var converted = mapSome(maybe, (v) => v.length);
var value = some(converted, 0); // == 0
```

### `MaybeMap` : a map with optional values (*aka Map>*)

```dart
var map = MaybeMap();
map["test"] = Maybe.nothing(); // doesn't add value
map["test"] = Maybe.some("value"); // adds value
when(map["test"], some: (v) => print(v));

map["test"] = Maybe.nothing(); // deletes key
when(map["test"], isNothing: (v) => print("deleted :" + map.containsKey("test").toString()));
```

```dart
Map maybeMap = {
"test": "value",
};
var maybeMap = MaybeMap.fromMap(maybeMap);
when(map["test"], some: (v) => print(v));
```

## What about quiver's `Optional` ?

The [Optional](https://github.com/google/quiver-dart/blob/master/lib/src/core/optional.dart) type has several similarities with `Maybe`, but there are several subtle differences.

### Optional can be `null`

Let's take a quick example :

```dart
class Update {
final Optional title;
final Optional description;

Update({Optional title, Optional description})
: this.title = title ?? Optional.absent(),
this.description = description ?? Optional.absent();
}

final update = Update(title: Optional.of('sample'));

update.title.ifPresent((v) {
print('title: $v');
});

update.description.ifPresent((v) {
print('description: $v');
});
```

Thanks to static functions, all can be replaced by :

```dart
class Update {
final Maybe title;
final Maybe description;

Update({this.title this.description});
}

final update = Update(title: Maybe.some('sample'));

when(update.title, some: (v) {
print('title: $v');
});

when(update.description, some: (v) {
print('description: $v');
});
```

So, the critical part is that you can forget that `Optional` can be `null` itself and produce exceptions (`update.title.ifPresent` in our example). You are then forced to test its nullity and you come back to the initial problematic. This is where `Maybe` feels more robust to me.

### `absent` is similar to `null`

With `Maybe`, values can be nullable.

In the following example, we explicitly say that the title should have a new `null` value.

```dart
class Update {
final Maybe title;
final Maybe description;

Update({ this.title, this.description});
}

final update = Update(title: Maybe.some(null, nullable: true);
```

This is really different than having a `nothing` title, which significates that the title shouldn't be modified.

```dart
final update = Update(title: Maybe.nothing());
```