【问题标题】:Why does ghc generate so many useless-looking nested case expressions?为什么 ghc 会生成这么多看起来无用的嵌套 case 表达式?
【发布时间】:2013-08-12 16:35:19
【问题描述】:

我有一些 Haskell 代码

indLoc index way = do
    Store p <- ask
    return $ plusPtr p localAddr
    where localAddr = (stHeader + stIndices + index + stIndices * way) * blockSize
--snip...
    (Just way, _) -> do
        liftIO $ pokeElemOff loc way a
        indLoc index way

这会产生一些看起来很奇怪的核心:

  case GHC.Prim.writeInt64OffAddr#
         @ GHC.Prim.RealWorld a4_s4UV i_s4UW x_s4UX new_s_s4UY
  of s2_s4V0 { __DEFAULT ->
  let {
    sat_s528 :: GHC.Ptr.Ptr b_a1UV
    [LclId]
    sat_s528 =
      case r_s4Us `cast` ... of _ { GHC.Ptr.Ptr addr_s4Vb ->
      case index_s4Um of _ { GHC.Types.I# y_s4Vc ->
      case ds1_s4Ub of _ { (blk1_s529, offs_s4V8) ->
      case offs_s4V8 of _ { GHC.Types.I# d_s4Vk ->
      case GHC.Prim.*# 2 i_s4UW of sat_s4Vf { __DEFAULT ->
      case GHC.Prim.+# 3 y_s4Vc of sat_s527 { __DEFAULT ->
      case GHC.Prim.+# sat_s527 sat_s4Vf of sat_s526 { __DEFAULT ->
      case GHC.Prim.*# sat_s526 4096 of sat_s4Vi { __DEFAULT ->
      case GHC.Prim.plusAddr# addr_s4Vb sat_s4Vi
      of sat_s525 { __DEFAULT ->
      case GHC.Prim.plusAddr# sat_s525 d_s4Vk of sat_s524 { __DEFAULT ->
      GHC.Ptr.Ptr @ b_a1UV sat_s524
      }
      }
      }
      }
      }
      }
      }
      }
      }
      } } in
  (# s2_s4V0, sat_s528 #)
  }

case 表达式看起来像是无操作。他们在那里做什么?严格吗?

【问题讨论】:

    标签: haskell


    【解决方案1】:

    case 表达式强制评估。使用 let 将改为构建闭包。请注意,GHC Core 在case 的语义上与常规 Haskell 不同。

    【讨论】:

    • 这是否意味着编译为一系列算术指令? (我尝试阅读 llvm 转储,它非常难以理解。)
    • 是的,就是这样。
    • 或许向核心添加一些浅层语法以使其更具可读性会很有用?像“force x in ...”之类的东西是“case x of _ -> ...”的语法糖?我知道核心不打算被普通用户阅读,但专家也是用户;)
    • 引擎盖下已经有some readability magic。此外,GHC 不会缩进单分支 case 表达式的主体 - 所以实际上手动发现也不难。
    猜你喜欢
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    • 1970-01-01
    • 1970-01-01
    • 2016-05-03
    • 1970-01-01
    相关资源
    最近更新 更多