Skip to content

Simplifier undoes manual floating, leading to arity decrease

Consider this program:

{-# OPTIONS_GHC -O2 -fforce-recomp #-}
{-# LANGUAGE MagicHash, UnboxedTuples #-} 

module Lib (pap) where

blah :: String -> (# Char, String #)
blah xs = (# 'c', xs #)
{-# NOINLINE blah #-}

lvl :: (Char, String)
lvl = case blah "foo" of (# x, xs #) -> (x, xs)

go :: String -> Int -> Int
go xs n = length xs + n
{-# NOINLINE go #-}

pap :: Int -> Int
pap = case lvl of (x, xs) -> go (x:xs)
{-# NOINLINE pap #-}

Simplified output of pap:

-- RHS size: {terms: 19, types: 13, coercions: 0, joins: 0/1}
pap [InlPrag=NOINLINE] :: Int -> Int
[GblId]
pap
  = case blah_rgw lvl2_r17d of { (# ipv_s14q, ipv1_s14r #) ->
    let {
      xs_s16X :: String
      [LclId, Unf=OtherCon []]
      xs_s16X = GHC.Types.: @Char ipv_s14q ipv1_s14r } in
    \ (n_s16Y :: Int) ->
      case n_s16Y of { GHC.Types.I# ww_s170 ->
      case $wgo_r17b xs_s16X ww_s170 of ww1_s175 { __DEFAULT ->
      GHC.Types.I# ww1_s175
      }
      }
    }

I certainly would have expected pap to have arity 1 since I have so carefully floated out the CAF lvl. But it appears the Simplifier happily inlines lvl back into pap (because there is no intervening lambda, I presume), thereby decreasing the arity of pap to 0.

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