Dan*_*our 9 optimization performance haskell compile-time-constant compile-time
我目前正在学习Haskell,有一件事令我感到困惑:
当我构建一个复杂的表达式(其计算需要一些时间)并且该表达式是常量(意味着它只构建已知的硬编码值)时,不会在编译时计算表达式.
来自C/C++背景我习惯于这种优化.
在Haskell/GHC中不执行此类优化(默认情况下)的原因是什么?有什么好处,如果有的话?
data Tree a =
EmptyTree
| Node a (Tree a) (Tree a)
deriving (Show, Read, Eq)
elementToTree :: a -> Tree a
elementToTree x = Node x EmptyTree EmptyTree
treeInsert :: (Ord a) => a -> Tree a -> Tree a
treeInsert x EmptyTree = elementToTree x
treeInsert x (Node a left right)
| x == a = Node x left right
| x < a = Node a (treeInsert x left) right
| x > a = Node a left (treeInsert x right)
treeFromList :: (Ord a) => [a] -> Tree a
treeFromList [] = EmptyTree
treeFromList (x:xs) = treeInsert x (treeFromList xs)
treeElem :: (Ord a) => a -> Tree a -> Bool
treeElem x EmptyTree = False
treeElem x (Node a left right)
| x == a = True
| x < a = treeElem x left
| x > a = treeElem x right
main = do
let tree = treeFromList [0..90000]
putStrLn $ show (treeElem 3 tree)
Run Code Online (Sandbox Code Playgroud)
由于这将始终打印,True我希望编译的程序几乎立即打印和退出.
Dan*_*ner 15
你可能会喜欢这个reddit线程.编译器可以尝试这样做,但它可能是危险的,因为任何类型的常量都可以做有趣的事情,比如循环.至少有两种解决方案:一种是超级编译,但尚未作为任何编译器的一部分提供,但您可以尝试各种研究人员的原型; 更实际的是使用Template Haskell,这是GHC的机制,让程序员要求在编译时运行一些代码.
在这种情况下,GHC 无法确定计算是否会完成。这不是一个懒惰与严格的问题,而是一个停止的问题。对您来说,说这treeFromlist [0..90000]是一个可以在编译时计算的常量看起来很简单,但是编译器如何知道这一点呢?编译器可以轻松优化[0..90000]为常量,但您甚至不会注意到这种变化。
| 归档时间: |
|
| 查看次数: |
1484 次 |
| 最近记录: |