Skip to content

Instantly share code, notes, and snippets.

@dhilst
Created January 4, 2026 04:19
Show Gist options
  • Select an option

  • Save dhilst/cc286577a072835a3f0e28234a14c3eb to your computer and use it in GitHub Desktop.

Select an option

Save dhilst/cc286577a072835a3f0e28234a14c3eb to your computer and use it in GitHub Desktop.
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