考虑以下玩具示例:
someNum :: Int
someNum = 42
funcCommon :: Int -> Int
funcCommon x = x + 1
func1 :: Int -> (Int -> Int) -> Int
func1 x f = f x
func2 :: Int -> (Int -> Int) -> Int
func2 x f = f x
f1 = func1 someNum funcCommon
f2 = func2 someNum funcCommon
main = do
print f1
print f2
将相同的参数 funcCommon 和 someNum 作为参数应用到func1和func2,因此我们得到了func1和func2分别声明的情况(是不同的函数)但是两者最终都使用相同的参数调用了相同的函数。那么实际上会评估几次 funcCommon someNum ?结果是否可以重用,并且对 funcCommon someNum 仅进行一次评估?
答案 0 :(得分:1)
严格来讲,该语言并没有定义对它进行一次,两次或37次评估,或者对某特定次数进行评估甚至意味着什么。它所保证的就是遵守严格性规则,即
f1, f2 :: [Int]
f1 = repeat 1
f2 = error "evil"
main = do
print f1
print f2
您可以确定不会触发该错误,因为打印f1
实际上将永远吐出1
位,因此f2
的计算准确为零。
对于某些特定情况,编译器实际上可以在编译时对f1
和f2
进行所有计算,而在运行时都不会“评估”它们。
在实践中,您应该期望进行两次评估。确认两个函数执行相同的操作是一个难题,因此编译器通常不会打扰。