Skip to content

Appending the empty list

Daniel Wagner wrote this rather simple and idiomatic bit of code:

select :: (t -> Bool) -> [t] -> [a] -> [a]
select p xs = concat . zipWith (\x y -> [y | p x]) xs

I was rather surprised by the Core:

select :: forall t a. (t -> Bool) -> [t] -> [a] -> [a]
[GblId,
 Arity=3,
 Caf=NoCafRefs,
 Str=<L,C(U)><S,1*U><L,1*U>,
 Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,
         WorkFree=True, Expandable=True, Guidance=IF_ARGS [60 0 0] 270 0}]
select
  = \ (@ t_aGU)
      (@ a_aGV)
      (p_atT :: t_aGU -> Bool)
      (xs_atU :: [t_aGU])
      (eta_B1 :: [a_aGV]) ->
      letrec {
        go2_a1BN [Occ=LoopBreaker] :: [t_aGU] -> [a_aGV] -> [a_aGV]
        [LclId, Arity=2, Str=<S,1*U><L,1*U>, Unf=OtherCon []]
        go2_a1BN
          = \ (ds_a1BO :: [t_aGU]) (_ys_a1BP :: [a_aGV]) ->
              case ds_a1BO of {
                [] -> GHC.Types.[] @ a_aGV;
                : ipv_a1BS ipv1_a1BT ->
                  case _ys_a1BP of {
                    [] -> GHC.Types.[] @ a_aGV;
                    : ipv2_a1BX ipv3_a1BY ->
                      case p_atT ipv_a1BS of {
                        False ->
                          ++ @ a_aGV (GHC.Types.[] @ a_aGV) (go2_a1BN ipv1_a1BT ipv3_a1BY);
                        True ->
                          GHC.Base.++_$s++
                            @ a_aGV
                            (go2_a1BN ipv1_a1BT ipv3_a1BY)
                            ipv2_a1BX
                            (GHC.Types.[] @ a_aGV)
                      }
                  }
              }; } in
      go2_a1BN xs_atU eta_B1

I'm not sure what's going on in the True branch, but the False branch looks a bit fishy:

++ @ a_aGV (GHC.Types.[] @ a_aGV) (go2_a1BN ipv1_a1BT ipv3_a1BY);

Why isn't the [] ++ optimized away?

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information