繁体   English   中英

Perl ala Haskell中的模式匹配

[英]Pattern matching in Perl ala Haskell

在Haskell(F#,Ocaml等)中,我可以这样做:

sign x |  x >  0        =   1
       |  x == 0        =   0
       |  x <  0        =  -1

计算给定整数的符号。

这可以简洁地表达某些逻辑流程。 我在Perl中遇到了其中一种流程。

现在我正在做的是

sub frobnicator
{
   my $frob = shift;
   return "foo" if $frob eq "Foomaticator";
   return "bar" if $frob eq "Barmaticator";
   croak("Unable to frob legit value: $frob received");
}

感觉不好意思而且丑陋。

该代码必须在Perl 5.8.8上运行,但是我当然也对更现代的技术感兴趣。

这是另一种可能的方法,仍然有些罗word,但也许可以更好地反映流程。 (在《 Perl最佳实践》一书中,作者建议大多数情况下避免使用if的后缀形式,因为您需要从头到尾进行扫描以了解所发生的情况。)可以添加括号以帮助突出该条件。

sub sign
{
    my $x = shift;
    $x  > 0  and return  1;
    $x == 0  and return  0;
    $x  < 0  and return -1;
}

sub frobnicator
{
    my $frob = shift;

    $frob eq "Foomaticator" and return "foo";
    $frob eq "Barmaticator" and return "bar";

    croak("Unable to frob legit value: $frob received");
}

您可以使用条件运算符:

sub frobnicator {
  my $frob = shift;
  return $frob eq 'Foomaticator' ? 'foo' :
         $frob eq 'Barmaticator' ? 'bar' :
         croak("Unable to frob legit value: $frob received");
}

它将您的原始示例变为:

sub sign {
  my $x = shift;
  return $x < 0 ? -1 :
         $x > 0 ?  1 :
                   0 ;
}

您知道,这有点丑陋,但它可以使您理解:-)

sub sign { 
    my $x = shift;
    return $x <=> 0;
}

富有表现力? 如果您知道“太空飞船”操作员的工作,那么可以。 如果没有,那就不多了。 我想说,一段Perl代码对您的表现力完全取决于您对Perl的熟悉程度。

我必须说我不知道​​你在追求什么。 对我来说,您的示例中的代码非常清晰,而且一点也不难看。 perl中总是有替代方法,因此:

sub frobnicator
{
   my $frob = shift;
   my %frobs = (
       Foomaticator    => "foo",
       Barmaticator    => "bar",
   );
   return $frobs{$frob} //  # If $frob is a defined key, return it
       croak("Unable to frob legit value: $frob received");
}

略少精确,但也许更友好的较旧的perl版本使用|| 代替//

对于Perl 5.10或更高版本,它具有以下优点:

给定

...这将允许:

...
use feature qw( switch say);
use Carp;
sub frobnicator {
    my $frob = shift;
    given ($frob) {
        when ('Foomaticator') {
            return q(foo);
        }
        when ('Barmaticator') {
            return q(bar);
        }
        default {
            croak(qq(Unable to frob legit value: $frob received));
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM