Created
January 4, 2026 04:19
-
-
Save dhilst/cc286577a072835a3f0e28234a14c3eb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use v5.10; | |
| use Data::Dumper; | |
| use Carp; | |
| sub aref { \@_ } | |
| package Opt { | |
| use overload | |
| '""' => \&stringinfy; | |
| sub new { | |
| my ($cls, $tag, $payload) = @_; | |
| bless { | |
| tag => $tag, | |
| payload => $payload, | |
| }, $cls; | |
| } | |
| sub value { | |
| shift->{payload}; | |
| } | |
| sub some { | |
| Opt->new("some", shift); | |
| } | |
| sub none { | |
| Opt->new("none"); | |
| } | |
| sub is_some { | |
| shift->{tag} eq "some"; | |
| } | |
| sub map(&$) { | |
| my ($block, $self) = @_; | |
| if ($self->is_some) { | |
| local $_ = $self->value; | |
| return some($block->()); | |
| } else { | |
| return $self; | |
| } | |
| } | |
| sub default(&$) { | |
| my ($block, $self) = @_; | |
| return $block->() unless $self->is_some; | |
| $self->value; | |
| } | |
| sub stringinfy { | |
| my ($self) = @_; | |
| if ($self->is_some) { | |
| return "Some(" . $self->value . ")"; | |
| } else { | |
| return "None" | |
| } | |
| } | |
| sub bind(&$) { | |
| my ($block, $self) = @_; | |
| if ($self->is_some) { | |
| local $_ = $self->value; | |
| return $block->(); | |
| } else { | |
| return $self; | |
| } | |
| } | |
| } | |
| package Opt::Match { | |
| sub some(&$) { | |
| my ($block, $self) = @_; | |
| return $self unless ref($self) eq "Opt"; | |
| if ($self->is_some) { | |
| local $_ = $self->value; | |
| return $block->(); | |
| } else { | |
| return $self; | |
| } | |
| } | |
| sub none(&$) { | |
| my ($block, $self) = @_; | |
| return $self unless ref($self) eq "Opt"; | |
| if (! $self->is_some()) { | |
| local $_ = undef; | |
| return $block->(); | |
| } else { | |
| return $self; | |
| } | |
| } | |
| } | |
| my $some = Opt::some(1); | |
| my $none = Opt::none(); | |
| say | |
| Opt::default { "oops" } | |
| Opt::map { $_ + 2 } | |
| Opt::map { $_ + 1 } | |
| $some; | |
| say | |
| Opt::Match::some { 1 } | |
| Opt::Match::none { 0 } | |
| Opt::bind { $_ > 0 ? Opt::some($_ - 1) : Opt::none() } | |
| Opt::bind { $_ > 0 ? Opt::some($_ - 1) : Opt::none() } | |
| Opt::none(10); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment