Was is the idiomatic way to define partial functions in Perl?

75 Views Asked by At

What is the most common/idiomatic way to define partial functions in Perl, that is functions that are not defined on all inputs. For example, in Haskell we have

safeHead :: [a] -> Maybe a
safeHead [] = Nothing
safeHead (x:xs) = Just x

in C we have

int factorial(int n) {
     assert(n >= 0);
     int result = 1;
     while (n) result *= n--;
     return result;
}

or

int factorial(int n) {
     if (n < 0) return -1;
     int result = 1;
     while (n) result *= n--;
     return result;
}

I would rather not import a CPAN module.

1

There are 1 best solutions below

0
ikegami On BEST ANSWER

Like in C, you can return from the middle of Perl subs.

sub factorial {
   my $n = shift;

   return -1 if $n < 0;

   my $acc = 1;
   $acc *= $_ for 2 .. $n;
   return $acc;
}

Assertion-style:

sub factorial {
   my $n = shift;

   $n >= 0
      or return -1;

   my $acc = 1;
   $acc *= $_ for 2 .. $n;
   return $acc;
}

If I were to use return here, I'd probably return undef rather than -1. Any misuse of this returned value should be noisy.

But I would more likely throw an exception (using croak) for invalid inputs.


A side note on how to check for different return values.

if condition return false;
return 0;
return "";
return "0";
return undef; return;
my $x = f() False condition False condition False condition
defined( my $x = f() ) True condition False condition False condition
my ( $x ) = f() True condition True condition False condition