view release on metacpan or search on metacpan
Functional.pm view on Meta::CPAN
$x = Until { shift() % 10 == 0 } \&inc, 1; # 10
In Haskell:
until :: (a -> Bool) -> (a -> a) -> a -> a
until p f x = if p x then x else until p f (f x)
=cut
sub Until(&&$);
sub Until(&&$) {
my($p, $f, $x) = @_;
return $x if $p->($x);
return Until(\&$p, \&$f, $f->($x));
}
=item fst x:xs
Returns the first element in a tuple. eg:
Functional.pm view on Meta::CPAN
$x = Map { double(shift) } [1..6]; # [2, 4, 6, 8, 10, 12]
In Haskell:
map :: (a -> b) -> [a] -> [b]
map f xs = [ f x | x <- xs ]
=cut
sub Map(&$) {
my($f, $xs) = @_;
tie my @a, 'InfiniteList', sub {
my($array, $idx) = @_;
return $f->($xs->[$idx]);
}, scalar @{$xs};
return \@a;
}
=item filter p xs
Functional.pm view on Meta::CPAN
In Haskell:
filter :: (a -> Bool) -> [a] -> [a]
filter p xs = [ x | x <- xs, p x ]
=cut
# Ha! Before infinite lists simply consisted of:
# return [grep { $f->($_) } @{$xs}];
sub filter(&$) {
my($f, $xs) = @_;
my $pointer = -1;
tie my @a, 'InfiniteList', sub {
my($array, $idx) = @_;
my $debug = 0;
print "$idx: in (done $pointer)\n" if $debug;
if ($pointer eq $INFINITE) {
die "Fetching an infinite amount of values in filter()!\n";
}
if ($idx - 1 > $pointer) {
Functional.pm view on Meta::CPAN
$x = foldl { shift() + shift() } 0, [1..6]; # 21
In Haskell:
foldl :: (a -> b -> a) -> a -> [b] -> a
foldl f z [] = z
foldl f z (x:xs) = foldl f (f z x) xs
=cut
sub foldl(&$$) {
my($f, $z, $xs) = @_;
map { $z = $f->($z, $_) } @{$xs};
return $z;
}
=item foldl1 f xs
This is a variant of foldl where the first value of
xs is taken as z. Applies function f to the pairs (xs[0], xs[1]),
Functional.pm view on Meta::CPAN
$x = foldl1 { shift() + shift() } [1..6]; # 21
In Haskell:
foldl1 :: (a -> a -> a) -> [a] -> a
foldl1 f (x:xs) = foldl f x xs
=cut
sub foldl1(&$) {
my($f, $xs) = @_;
my $z = shift @{$xs};
return foldl(\&$f, $z, $xs);
}
=item scanl f q xs
Returns a list of all the intermedia values that foldl would compute.
ie returns the list z, f(z, xs[0]), f(f(z, xs[0]), xs[1]), f(f(f(z,
Functional.pm view on Meta::CPAN
In Haskell:
scanl :: (a -> b -> a) -> a -> [b] -> [a]
scanl f q xs = q : (case xs of
[] -> []
x:xs -> scanl f (f q x) xs)
=cut
sub scanl(&$$) {
my($f, $q, $xs) = @_;
# Ha! Before infinite lists simply consisted of the elegant:
# my @return = $q;
# map { $q = $f->($q, $_); push @return, $q } @{$xs};
# return [@return];
my $pointer = -1;
tie my @a, 'InfiniteList', sub {
my($array, $idx) = @_;
my $debug = 0;
print "$idx: in (done $pointer)\n" if $debug;
Functional.pm view on Meta::CPAN
$x = scanl1 { shift() + shift() } [1..6]; # [1, 3, 6, 10, 15, 21]
In Haskell:
scanl1 :: (a -> a -> a) -> [a] -> [a]
scanl1 f (x:xs) = scanl f x xs
=cut
sub scanl1(&$) {
my($f, $xs) = @_;
my $z = shift @{$xs};
return scanl(\&$f, $z, $xs);
}
=item foldr f z xs
This is similar to foldl but is folding from the right instead of the
left. Note that foldr should not be done to infinite lists. eg: the
Functional.pm view on Meta::CPAN
$x = foldr { shift() + shift() } 0, [1..6] ; # 21
In Haskell:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f z [] = z
foldr f z (x:xs) = f x (foldr f z xs)
=cut
sub foldr(&$$) {
my($f, $z, $xs) = @_;
map { $z = $f->($_, $z) } reverse @{$xs};
return $z;
}
=item foldr1 f xs
This is similar to foldr1 but is folding from the right instead of the
left. Note that foldr1 should not be done on infinite lists. eg:
Functional.pm view on Meta::CPAN
$x = foldr1 { shift() + shift() } [1..6]; # 21
In Haskell:
foldr1 :: (a -> a -> a) -> [a] -> a
foldr1 f [x] = x
foldr1 f (x:xs) = f x (foldr1 f xs)
=cut
sub foldr1(&$) {
my($f, $xs) = @_;
my $z = pop @{$xs};
return foldr(\&$f, $z, $xs);
}
=item scanr f z xs
This is similar to scanl but is scanning and folding
from the right instead of the left. Note that scanr should
Functional.pm view on Meta::CPAN
In Haskell:
scanr :: (a -> b -> b) -> b -> [a] -> [b]
scanr f q0 [] = [q0]
scanr f q0 (x:xs) = f x q : qs
where qs@(q:_) = scanr f q0 xs
=cut
sub scanr(&$$) {
my($f, $z, $xs) = @_;
my @return = $z;
map { $z = $f->($_, $z); push @return, $z; } reverse @{$xs};
return [@return];
}
=item scanr1 f xs
This is similar to scanl1 but is scanning and folding
Functional.pm view on Meta::CPAN
In Haskell:
scanr1 :: (a -> a -> a) -> [a] -> [a]
scanr1 f [x] = [x]
scanr1 f (x:xs) = f x q : qs
where qs@(q:_) = scanr1 f xs
=cut
sub scanr1(&$) {
my($f, $xs) = @_;
my $z = pop @{$xs};
return scanr(\&$f, $z, $xs);
}
=item iterate f x
This returns the infinite list (x, f(x), f(f(x)), f(f(f(x)))...) and
so on. eg:
Functional.pm view on Meta::CPAN
$x = take(8, iterate { shift() * 2 } 1);
# [1, 2, 4, 8, 16, 32, 64, 128]
In Haskell:
iterate :: (a -> a) -> a -> [a]
iterate f x = x : iterate f (f x)
=cut
sub iterate(&$) {
my($f, $x) = @_;
tie my @a, 'InfiniteList', sub {
my($array, $idx) = @_;
return $x if $idx == 0;
return $f->($array->FETCH($idx-1));
};
return \@a;
}
Functional.pm view on Meta::CPAN
In Haskell:
takeWhile :: (a -> Bool) -> [a] -> [a]
takeWhile p [] = []
takeWhile p (x:xs)
| p x = x : takeWhile p xs
| otherwise = []
=cut
sub takeWhile(&$) {
my($p, $xs) = @_;
# Ha! Before infinite lists simply consisted of:
# my @return;
# push @return, $_ while($_ = shift @{$xs} and $p->($_));
# return [@return];
my $pointer = -1;
tie my @a, 'InfiniteList', sub {
my($array, $idx) = @_;
my $debug = 0;
print "$idx: in (done $pointer)\n" if $debug;
Functional.pm view on Meta::CPAN
In Haskell:
dropWhile :: (a -> Bool) -> [a] -> [a]
dropWhile p [] = []
dropWhile p xs@(x:xs')
| p x = dropWhile p xs'
| otherwise = xs
=cut
sub dropWhile(&$) {
my($p, $xs) = @_;
# Ha! Before infinite lists simply consisted of:
# shift @{$xs} while($_ = @{$xs}[0] and $p->($_));
my $pointer = 0;
while (1) {
last unless $p->($xs->[$pointer]);
$pointer++;
}
print "Pointer = $pointer\n" if 0;
my $len = scalar @{$xs};
Functional.pm view on Meta::CPAN
span :: (a -> Bool) -> [a] -> ([a],[a])
span p [] = ([],[])
span p xs@(x:xs')
| p x = (x:ys, zs)
| otherwise = ([],xs)
where (ys,zs) = span p xs'
=cut
sub span(&$) {
my($p, $xs) = @_;
my @xs = @{$xs};
return [takeWhile(\&$p, $xs), dropWhile(\&$p, \@xs)];
}
=item break p xs
Splits xs into two lists, the first containing the first few elements
for which p(that element) is false. eg:
$x = break { shift() >= 4 }, [1..6]; # [[1, 2, 3], [4, 5, 6]]
In Haskell:
break :: (a -> Bool) -> [a] -> ([a],[a])
break p = span (not . p)
=cut
sub break(&$) {
my($p, $xs) = @_;
return span(sub { not $p->(@_) }, $xs);
}
=item lines s
Breaks the string s into multiple strings, split at line
boundaries. eg:
Functional.pm view on Meta::CPAN
$x = any { even(shift) } [1, 2, 3]; # 1
In Haskell:
any :: (a -> Bool) -> [a] -> Bool
any p = or . map p
=cut
sub any(&$) {
my($p, $xs) = @_;
my $n = 0;
my $size = $#{$xs};
while ($n <= $size) {
return 1 if $p->($xs->[$n]);
$n++;
}
if ($size == $Language::Functional::INFINITE
or $size == $Language::Functional::INFINITE - 1
) {
Functional.pm view on Meta::CPAN
$x = all { odd(shift) } [1, 1, 3]; # 1
In Haskell:
all :: (a -> Bool) -> [a] -> Bool
all p = and . map p
=cut
sub all(&$) {
my($p, $xs) = @_;
my $n = 0;
my $size = $#{$xs};
while ($n <= $size) {
return 0 if not $p->($xs->[$n]);
$n++;
}
if ($size == $Language::Functional::INFINITE
or $size == $Language::Functional::INFINITE - 1
) {