为什么在Haskell编译时不会评估(常量)表达式? [英] Why are (constant) expressions not evaluated at compile time in Haskell?
问题描述
当我构建一个复杂的表达式(其计算需要一些时间)并且这个表达式是不变的(意味着它只是构建已知的硬编码值),表达式不会在编译时计算。
从C / C ++背景中输入我用到这种类型的优化。
在Haskell / GHC中, NOT 执行这种优化(默认情况下)的原因是什么?什么是优点,如果有的话?
数据树a =
EmptyTree
|节点a(Tree a)(Tree a)
派生(Show,Read,Eq)
elementToTree :: a - >树a
elementToTree x =节点x EmptyTree EmptyTree
treeInsert ::(Ord a)=> a - >树a - >树a
treeInsert x EmptyTree = elementToTree x
treeInsert x(节点左右)
| x == a = Node x左右
| x < a =节点a(treeInsert x left)右边
| x> a =节点左(treeInsert x右)
treeFromList ::(Ord a)=> [a] - >树a
treeFromList [] = EmptyTree
treeFromList(x:xs)= treeInsert x(treeFromList xs)
treeElem ::(Ord a)=> a - >树a - > Bool
treeElem x EmptyTree = False
treeElem x(节点左右)
| x == a =真
| x < a = treeElem x离开
| x> a = treeElem x right
main = do
let tree = treeFromList [0..90000]
putStrLn $ show(treeElem 3 tree)
因为这会始终 打印真实
我期望编译的程序几乎可以立即打印并退出
。 您可能会喜欢这是reddit线程。编译器可以尝试做到这一点,但它可能是危险的,因为任何类型的常量都可以做循环等有趣的事情。至少有两种解决方案:一种是超级编译,不能作为任何编译器的一部分,但您可以尝试各种研究人员的原型;更实用的是使用Template Haskell,这是GHC让程序员要求在编译时运行一些代码的机制。
I am currently learning Haskell, and there is one thing that baffles me:
When I build a complex expression (whose computation will take some time) and this expression is constant (meaning it is build only of known, hard coded values), the expression is not evaluated at compile time.
Comming from a C/C++ background I am used to such kind of optimization.
What is the reason to NOT perform such optimization (by default) in Haskell / GHC ? What are the advantages, if any?
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)
As this will always print True
I would expect the compiled programm to print and exit
almost immediately.
You may like this reddit thread. The compiler could try to do this, but it could be dangerous, as constants of any type can do funny things like loop. There are at least two solutions: one is supercompilation, not available as part of any compiler yet but you can try prototypes from various researchers; the more practical one is to use Template Haskell, which is GHC's mechanism for letting the programmer ask for some code to be run at compile time.
这篇关于为什么在Haskell编译时不会评估(常量)表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!