Cookie Notice

As far as I know, and as far as I remember, nothing in this page does anything with Cookies.

2015/01/07

A Higher Order Idea stolen from Ramda.js

Start with Paul Bennett, who is a Perl guy I know from Google Plus. He pointed to a function in Ramda.js, which allows you to create a number of filters as anonymous functions, put them in an array, pass that array, and do that test in one line.

  1. // Instead of   
  2.   
  3. if ( x > 10 && x % 2 --- 0 ) { console.log( 'Big and Even' ) }  
  4.   
  5. var gt10 = function(x) { return x > 10 }  
  6. var even = R.allPredicates( [ gt10,even ] ) ;  
  7.   
  8. if ( f( x ) ) { console.log( 'Big and Even' ) }  

Now, imagine if we're testing several things, rather than just one.

I thought "Hey, there's so much I could do with this in Perl. I've been thinking about writing a mail filter that takes a function Higher Order Perl style, so could generate a function based on the config file and pass it into the middle of Mail::IMAPClient so I don't have to generate a menagerie of one-trick ponies. This, of course, is a fairly big idea to work with, and the allPredicates is small enough that, with a half-hour of working through Perl I mostly thought I knew, I came up with this. Fifteen lines of code. I am happy.

#!/usr/bin/env perl
use feature qw'say state' ;
use strict ;
use utf8 ;
use warnings ;
use Data::Dumper ;
# https://plus.google.com/u/0/+PaulBennett/posts/EvLLxiAMjKR
# http://ramdajs.com/docs/R.html
# SAMPLE CODE
# var gt10 = function(x) { return x > 10; };
# var even = function(x) { return x % 2 === 0};
# var f = R.allPredicates([gt10, even]);
# f(11); //=> false
# f(12); //=> true
my $gt10 = sub { my $i = shift ; return $i > 10 } ;
my $even = sub { my $i = shift ; return $i % 2 == 0 } ;
my $odd = sub { my $i = shift ; return $i % 2 == 1 } ;
my $test = sub { say Dumper \@_ } ;
# my $f = allPredicates( $test ) ;
my $f = allPredicates( $gt10 , $even ) ;
my $g = allPredicates( $gt10 , $odd ) ;
for my $i ( 9 .. 20 ) {
if ( &$f( $i ) ) { say $i . ' big and even' }
}
for my $i ( map { $_ * 3 } 1 .. 10 ) {
if ( &$g( $i ) ) { say $i . ' big and odd' }
}
# say &$gt10( 1 );
# say &$gt10( 12 );
# say &$even( 1 );
# say &$even( 12 );
# say &$odd( 1 );
# say &$odd( 12 );
sub allPredicates {
my @functions = @_ ;
my $function = sub {
my $val = shift ;
my @tests = @functions ;
my @results ;
for my $t ( @tests ) {
my $r = &$t( $val ) ;
push @results, $r if $r ;
}
return 1 if scalar @tests == scalar @results ;
return 0 ;
} ;
return $function ;
}
view raw allPredicates hosted with ❤ by GitHub

No comments:

Post a Comment