user6428287
user6428287

Reputation:

Implicit pattern matching in Haskell

Should one expect performance differences between these two emptys, or is it merely a matter of stylistic preference?

foo list = case list of
   []      -> True
   (_ : _) -> False

bar list = case list of
   (_ : _) -> False
   _       -> True

Upvotes: 2

Views: 186

Answers (1)

jberryman
jberryman

Reputation: 16645

In general you should not expect performance to change predictably between trivial fiddling around with patterns like what you're asking about, and can often expect the generated code to be identical.

But the way to actually check is to look at core and or benchmark with criterion. In this case the generated code is the same, and indeed GHC seems to actually combine them:

I compiled the snippet above with

ghc -Wall -O2 -ddump-to-file -ddump-simpl -dsuppress-module-prefixes -dsuppress-uniques -fforce-recomp  YourCode.hs

And we see this core:

foo :: forall t. [t] -> Bool
[GblId,
 Arity=1,
 Caf=NoCafRefs,
 Str=DmdType <S,1*U>,
 Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
         WorkFree=True, Expandable=True,
         Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False)
         Tmpl= \ (@ t) (list [Occ=Once!] :: [t]) ->
                 case list of _ [Occ=Dead] {
                   [] -> True;
                   : _ [Occ=Dead] _ [Occ=Dead] -> False
                 }}]
foo =
  \ (@ t) (list :: [t]) ->
    case list of _ [Occ=Dead] {
      [] -> True;
      : ds ds1 -> False
    }

-- RHS size: {terms: 1, types: 0, coercions: 0}
bar :: forall t. [t] -> Bool
[GblId,
 Arity=1,
 Caf=NoCafRefs,
 Str=DmdType <S,1*U>,
 Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
         WorkFree=True, Expandable=True,
         Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False)
         Tmpl= \ (@ t) (list [Occ=Once!] :: [t]) ->
                 case list of _ [Occ=Dead] {
                   [] -> True;
                   : _ [Occ=Dead] _ [Occ=Dead] -> False
                 }}]
bar = foo

I think the Tmpl stuff is the original implementation exposed for inlining in other modules, but I'm not certain.

Upvotes: 12

Related Questions