Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
* develop:
  add documentation on lazy/deferred identity
  • Loading branch information
Baptouuuu committed Jun 29, 2024
2 parents 4fc9114 + 8719f77 commit 22dce2b
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
51 changes: 51 additions & 0 deletions docs/structures/identity.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,54 @@ Let's say you have a string you want to camelize, here's how you'd do it:

!!! abstract ""
In the end this monad does not provide any behaviour, it's a different way to write and read your code.

## Lazy computation

By default the `Identity` apply each transformation when `map` or `flatMap` is called. But you can defer the application of the transformations to when the `unwrap` method is called. This can be useful when you're not sure the computed value will be really used.

Instead of using `Identity::of()` you'd do:

```php
$value = Identity::defer(static fn() => 'some value'); //(1)
// or
$value = Identity::lazy(static fn() => 'some value');
// then you can use the identity as before (see above)
```

1. Here the value is a string but you can use whatever type you want.

The difference between `lazy` and `defer` is that the first one will recompute the underlying value each time the `unwrap` method is called while the other one will compute it once and then always return the same value.

## Wrapping the underlying value in a `Sequence`

This monad has a `toSequence` method that will create a new [`Sequence`](sequence.md) containing the underlying value.

Both examples do the same:

=== "Declarative"
```php
$value = Identity::of('some value')
->toSequence();
```

=== "Imperative"
```php
$value = Sequence::of('some value');
```

On the surface this seems to not be very useful, but it becomes interesting when the identity is lazy or deferred. The laziness is propagated to the sequence.

Both examples do the same:

=== "Declarative"
```php
$value = Identity::lazy(static fn() => 'some value')
->toSequence();
```

=== "Imperative"
```php
$value = Sequence::lazy(static fn() => yield 'some value');
```

This combined to the [`Sequence::toIdentity()`](sequence.md#-toidentity) allows you to chain and compose sequences without having to be aware if the source sequence is lazy or not.
31 changes: 31 additions & 0 deletions docs/structures/sequence.md
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,37 @@ Let's say you have a sequence of strings representing the parts of a file and yo
??? note
Here `Content` and `File` are imaginary classes, but you can find equivalent classes in [`innmind/filesystem`](https://packagist.org/packages/innmind/filesystem).

??? tip
The [`Identity`](identity.md) returned carries the lazyness of the sequence. This allows composing sequences without having to be aware if the source is lazy or not.

=== "Lazy"
```php
$value = Sequence::lazy(static fn() => yield from \range(0, 100))
->toIdentity()
->toSequence();
// does the same as
$value = Sequence::lazy(
static fn() => yield Sequence::lazy(
static fn() => yield from \range(0, 100),
),
);
```

=== "InMemory"
```php
$value = Sequence::of(...\range(0, 100))
->toIdentity()
->toSequence();
// does the same as
$value = Sequence::of(
Sequence::of(
...\range(0, 100),
),
);
```

In both cases thanks to the `Identity` you only need to specify once if the whole thing is lazy or not.

### `->safeguard()`

This method allows you to make sure all values conforms to an assertion before continuing using the sequence.
Expand Down

0 comments on commit 22dce2b

Please sign in to comment.