GHC是否会像没有中间值一样有效地转换表达式? 例如 main = print $f ["aa", "bb", "cc"]f x = let a = map (map toUpper) x b = filter (\z - 'C' /= head z) a c = foldl1 (++) b in c 似乎有非常不同的核心输出(使用-
例如
main = print $f ["aa", "bb", "cc"] f x = let a = map (map toUpper) x b = filter (\z -> 'C' /= head z) a c = foldl1 (++) b in c
似乎有非常不同的核心输出(使用-ddump-simple)而不是
f x = foldl1 (++) $filter (\z -> 'C' /= head z) $map (map toUpper) x
具有中间值的表达式是否(显着)更长时间来评估?
线性使用中间let绑定相当于在值之间放置(.).GHC将通过这些管道融合.您可以从-ddump-simpl-stats的结果中看到
使用Bindings:
15 RuleFired 1 ++ 1 Class op /= 1 Class op show 1 Class op showList 1 filter 1 fold/build 1 foldr/app 1 map 1 neChar#->case 3 unpack 3 unpack-list
使用管道:
15 RuleFired 1 ++ 1 Class op /= 1 Class op show 1 Class op showList 1 filter 1 fold/build 1 foldr/app 1 map 1 neChar#->case 3 unpack 3 unpack-list
和同样融合的工人:
使用Bindings:
Main.main_go = \ (ds_aAz :: [[GHC.Types.Char]]) -> case ds_aAz of _ { [] -> GHC.Types.[] @ [GHC.Types.Char]; : y_aAE ys_aAF -> case GHC.Base.map @ GHC.Types.Char @ GHC.Types.Char GHC.Unicode.toUpper y_aAE of wild1_azI { [] -> GHC.List.badHead `cast` (UnsafeCo (forall a_azK. a_azK) [[GHC.Types.Char]] :: (forall a_azK. a_azK) ~ [[GHC.Types.Char]]); : x_azM ds1_azN -> case x_azM of _ { GHC.Types.C# c2_aAa -> case c2_aAa of _ { __DEFAULT -> GHC.Types.: @ [GHC.Types.Char] wild1_azI (Main.main_go ys_aAF); 'C' -> Main.main_go ys_aAF }
管道:
Main.main_go = \ (ds_aAA :: [[GHC.Types.Char]]) -> case ds_aAA of _ { [] -> GHC.Types.[] @ [GHC.Types.Char]; : y_aAF ys_aAG -> case GHC.Base.map @ GHC.Types.Char @ GHC.Types.Char GHC.Unicode.toUpper y_aAF of wild1_azB { [] -> GHC.List.badHead `cast` (UnsafeCo (forall a_azD. a_azD) [[GHC.Types.Char]] :: (forall a_azD. a_azD) ~ [[GHC.Types.Char]]); : x_azF ds1_azG -> case x_azF of _ { GHC.Types.C# c2_aA3 -> case c2_aA3 of _ { __DEFAULT -> GHC.Types.: @ [GHC.Types.Char] wild1_azB (Main.main_go ys_aAG); 'C' -> Main.main_go ys_aAG } }
你忘了用-O2编译吗?