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

Avatar for Masahiro Honma

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)