Peter
Peter Campbell Smith

Odd numbers and
odder references

Weekly challenge 171 — 27 June 2022

Week 171: 27 Jun 2022

Task 2

Task — First-class function

Create sub compose($f, $g) which takes in two parameters $f and $g as subroutine refs and returns subroutine reference such that:

compose($f, $g)->($x) = $f->($g->($x))

Analysis

This takes more thought than actual coding!

My solution assumes &$g can take any number of arguments, but returns a single value as an argument to &$f, which isn't quite what is asked, but I'm hoping is good enough.

I'm struggling to think of a real-life problem for which this might be the answer.

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

use v5.26;    # The Weekly Challenge - 2022-06-27
use utf8;     # Week 171 - task 2 - First class function
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';


# this is the compose function
sub compose {
    
    my ($f, $g) = @_;
    return sub {
        return $f->($g->(@_));
    }
}

# and here are some things to compose
sub sum        { return $_[0] + $_[1] };
sub difference { return $_[0] - $_[1] };
sub product    { return $_[0] * $_[1] };
sub quotient   { return $_[0] / $_[1] };

sub angles     { return qq[<< $_[0] >>] };
sub squares    { return qq{[[ $_[0] ]]} };
sub brackets   { return qq{(( $_[0] ))} };
sub curlies    { return qq[{{ $_[0] }}] };

# and some examples to show that it works
my $h;
$h = compose(\&angles, \&sum);
say &$h(5, 7) . ' : should be << 12 >>';

$h = compose(\&squares, \&difference);
say &$h(13, 11) . ' : should be [[ 2 ]]'; 

$h = compose(\&brackets, \&product);
say &$h(6, 7) . ' : should be (( 42 ))'; 

$h = compose(\&curlies, \&quotient);
say &$h(999, 111) . ' : should be {{ 9 }}'; 

Output


<< 12 >> : should be << 12 >>
[[ 2 ]] : should be [[ 2 ]]
(( 42 )) : should be (( 42 ))
{{ 9 }} : should be {{ 9 }}

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain