簡體   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