我有一段 Haskell 代码,如下所示:
fst . f $ (Z :. i `div` 2)
Z
和 :.
取自 Repa库并定义如下:data Z = Z deriving (Show, Read, Eq, Ord)
infixl 3 :.
data tail :. head = !tail :. !head deriving (Show, Read, Eq, Ord)
$
的表达权定义一个数组索引,而 f
是一个接受该索引并返回一对的函数。这编译为以下核心:case f_a2pC
(case ># x_s32E 0 of _ {
False ->
case <# x_s32E 0 of _ {
False -> :. Z (I# (quotInt# x_s32E 2));
True -> :. Z (I# (-# (quotInt# (+# x_s32E 1) 2) 1))
};
True ->
case <# x_s32E 0 of _ {
False -> :. Z (I# (quotInt# x_s32E 2));
True -> :. Z (I# (-# (quotInt# (+# x_s32E 1) 2) 1))
}
})
of _ { (x1_a2Cv, _) ->
x1_a2Cv
}
对我来说,中间 case 语句(以
># x_s32E 0
作为审查对象的语句)似乎很明显(也许是错误的)是多余的,因为两个分支是相同的。我能做些什么来摆脱它吗?我使用 Repa 文档中推荐的 GHC 选项编译我的代码:-O2 -Odph -fno-liberate-case -funfolding-use-threshold1000 -funfolding-keeness-factor1000
最佳答案
确实 case ># x_s32E 0 of
的两个分支是相同的,因此 case
是多余的。似乎 case
- 在两个分支变得相同后,不会运行相同分支的消除 - 可能值得一个错误报告。 This one可能是相关的,但由于为负除数生成的核心很好,我提交了 new bug .
使用更简单的 quot
- 如果 i
不能合法地否定 - 直接映射到机器除法运算符使代码更简单,因此不需要为此生成分支。
关于haskell - 从 Haskell 的核心中删除带有重复分支的 "case",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13139875/