Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Lens : Smart setter for immutable data

Lens : Smart setter for immutable data

A implementation of lens library in Perl

Masahiro Honma

August 29, 2014
Tweet

More Decks by Masahiro Honma

Other Decks in Technology

Transcript

  1. immutable data package Talk; use Moo; has speaker => (

    is => ’ro’, requires => 1 ); has name => ( is => ’ro’, requires => 1 );
  2. Nested immutable data setter won’t work well # Can’t write

    it $new_schedule = $schedule->talk->speaker ->name("hiratara");
  3. Nested immutable data Must copy and copy and copy ...

    $new_speaker = Speaker->new( name => "hiratara", age => $speaker->age, mail => $speaker->age, ); $new_talk = Talk->new( title => $talk->title, speaker => $new_speaker, ); $new_schedule = Schedule->new( talk => $new_talk, kind => $schedule->kind, );
  4. Ugly way to solve it Though, I hate mutable data.

    package Talk; use Moo; has speaker => ( is => ’rw’, requires => 1 ); has name => ( is => ’rw’, requires => 1 );
  5. Another way : use Lens Lens acts like an accessor

    # getter (will get ’hiratara’) (talk . speaker . name)->($schedule); # setter $new_schedule = (talk . speaker . name)->($schedule, ’hiratara’);
  6. This is monad M ηM // D D D D

    D D D D D D D D D D D D MM µ  M Mη oo zzzzzzzz zzzzzzzz M MMM Mµ // µM  MM µ  MM µ // M
  7. comonad is a dual of monad W WW ϵW oo

    Wϵ // W W EEEEEEEE EEEEEEEE δ OO y y y y y y y y y y y y y y y y WWW WW Wδ oo WW δW OO W δ oo δ OO
  8. costate comonad in Perl package Comonad::Costate; use Moo; extends ’Comonad’;

    has func => (is => ’ro’); has state => (is => ’ro’); sub counit my $self = shift; $self->func
  9. costate comonad in Perl sub map { my ($self, $f)

    = @_; (ref $self)->new( func => _comp($f, $self->func), state => $self->state, ); }
  10. costate comonad in Perl sub coflatten { my $self =

    shift; my $class = ref $self; my $self_func = $self->func; $class->new( func => sub { my $state = shift; $class->new( func => $self_func, state => $state, ); }, state => $self->state, ); }
  11. algebra of monad M MMX Mh // µX  MX

    h  MX h // X X ηX // C C C C C C C C C C C C C C C C MX h  X
  12. coalgebra of comonad W WWX WX Wh oo WX δX

    OO X h oo h OO X C C C C C C C C C C C C C C C C WX ϵX oo X h OO
  13. costate comonad coalgebra in Perl coalgebra => sub { my

    $data = shift; Comonad::Costate->new( func => sub { my $value = shift; (ref $data)->new( %$data, $field => $value, ) }, state => $data->$field, ); },
  14. costate comonad coalgebra costate comonad coalgebra is the combination of

    setter and getter. This is Lens. A → (AS × S) ≃ (A → AS) × (A → S) • A → AS is setter • A → S is getter
  15. composition of Lenses package Lens; use overload ( ’.’ =>

    ’chain’, fallback => 1, ); sub chain { my ($self, $other) = @_; Lens->new( coalgebra => sub { ... }, ); }
  16. Field lens sub lens ($) { my $field = shift;

    Lens->new( coalgebra => sub { my $data = shift; Comonad::Costate->new( func => sub { my $v = shift; (ref $data)->new(%$data, $field => $v) }, state => $data->$field, ); } ); }
  17. Lens is more powerful $schedule = (talk . speaker .

    name)->($schedule, ’hiratara’); # Setter and Getter of a part of string $schedule = (talk . speaker . name . substr_lens(3, 2)) ->($schedule, ’@’); # $schedule->talk->speaker->name will be "hir@ara"
  18. CONCLUSION • Lens is a good setter for immutable data

    • https://github.com/hiratara/p5-Lens To tell the truth, haskell’s lens implementation has the type: Let (−(V))V, −(S): SetSet → Set be functors (−(V))V ⇒ −(S)