From 7f38e74e781aaa78f8bc21ce0644fd501cc51807 Mon Sep 17 00:00:00 2001 From: MadMaurice Date: Fri, 2 Apr 2021 20:18:42 +0200 Subject: [PATCH] Add map, reduce and equal for lists --- lib/Minilisp.pm | 22 ++++++++++++++++++++++ t/lists.t | 4 ++++ 2 files changed, 26 insertions(+) diff --git a/lib/Minilisp.pm b/lib/Minilisp.pm index 72fbc6f..b3133fb 100644 --- a/lib/Minilisp.pm +++ b/lib/Minilisp.pm @@ -229,6 +229,28 @@ my %stdctx = ( 'first' => sub { return (shift)->[0]; }, 'second' => sub { return (shift)->[1]; }, 'nth' => sub { my ($idx,$list) = @_; return $list->[$idx]; }, + 'map' => sub { + my ($cb,$list) = @_; + die "map: First parameter must be a function" unless ref($cb) eq "CODE"; + die "map: Second parameter must be a list" unless ref($list) eq "ARRAY"; + + return [ map { $cb->($_) } @$list ]; + }, + 'reduce' => sub { + my ($cb,$list) = @_; + die "map: First parameter must be a function" unless ref($cb) eq "CODE"; + die "map: Second parameter must be a list" unless ref($list) eq "ARRAY"; + + my @copy = ( @$list ); + my $v = shift @copy; + $v = $cb->($v,$_) foreach (@copy); + return $v; + }, + # TODO: this is tricky as it needs to recurse into sub lists + 'equal' => sub { + my ($a, $b) = @_; + return @$a == @$b; + }, # Constants 't' => 1, diff --git a/t/lists.t b/t/lists.t index 80d9194..b079959 100644 --- a/t/lists.t +++ b/t/lists.t @@ -4,4 +4,8 @@ (expect "First element is 1" (= (first lst) 1)) (expect "Second element is 2" (= (second lst) 2)) (expect "Third element is 3" (= (nth 2 lst) 3)) + (expect "Equal to itself" (equal lst lst)) + (expect "Equal to identical list" (equal lst (list 1 2 3))) + (expect "Reduce with +" (= (reduce + lst) 6)) + (expect "Map doubling values" (equal (map (lambda (x) (* x 2)) lst) (list 2 4 6))) )