Performance 哈斯克尔';s`seq`对参数进行冗余求值?
如果我正确理解了讨论,Performance 哈斯克尔';s`seq`对参数进行冗余求值?,performance,haskell,Performance,Haskell,如果我正确理解了讨论,seq不应该对一个值求值两次,因为在x`seq`x中,应该对x求值一次 那我为什么会有这种行为呢 λ>:设置+s λ>设fib x=if x fib 30 832040 (2.49秒,638088448字节) λ>设x=fib 30 in x 832040 (2.47秒,638088792字节) λ>设x=fib 30 in x`seq`x 832040 (4.95秒,1276067128字节) 这显然是双重评价?我是不是误解了什么 编辑:正如下面所问的@danidiaz
seq
不应该对一个值求值两次,因为在x`seq`x
中,应该对x
求值一次
那我为什么会有这种行为呢
λ>:设置+s
λ>设fib x=if x fib 30
832040
(2.49秒,638088448字节)
λ>设x=fib 30 in x
832040
(2.47秒,638088792字节)
λ>设x=fib 30 in x`seq`x
832040
(4.95秒,1276067128字节)
这显然是双重评价?我是不是误解了什么
编辑:正如下面所问的@danidiaz,我也进行了评估
λ>(\x->x`seq`x)(fib 30)
832040
(2.51秒,638087888字节)
λ>设x=(fib 30)::x`seq`x中的Int
832040
(2.52秒,732476640字节)
现在更令人惊讶的是
编辑2:我发现这个问题已被标记为先前一个关于单态限制的问题的重复。当我遇到这个问题时,我不知道这是由于限制。因此,如果有人发现他/她处于我的位置,我想这个问题的答案会很有帮助。对于这个答案的第一部分,
:在ghci中设置-XnomonomoromogismRestriction
。这将在后面解释
天真地说,在Haskell中,让x=5 in(x+1,x+2)
始终等于(\x->(x+1,x+2))5
。但是它们有不同的类型
let x = 5 in (x + 1,x + 2) :: (Num a, Num b) => (a, b)
(\x -> (x + 1,x + 2)) 5 :: Num b => (b, b)
原因是Haskell的一个特性叫做。与lambda绑定标识符不同,在let
中绑定的标识符可以在let
的主体中以不同的方式实例化。例如:
ghci> let f = id in (f True, f 'a')
(True,'a')
ghci> (\f -> (f True, f 'a')) id
*** ERROR ***
现在,你没有给你的fib
函数一个类型签名,而被推断出来的是
fib :: (Ord a, Num a) => a -> a
这将适用于Num
的不同实例,如Int
、Float
等
但正因为如此,当您编写x`seq`x
时,ghci无法确定这两个x
实际上是同一类型的!如果它们可能不同,那么它们就不能被分享
这就是为什么(\x->x`seq`x)(fib 30)
确实有共享的原因。因为x
是lambda绑定的,所以编译器确保两个实例的值确实相同。对于let x=(fib 30)::x`seq`x
中的Int,因为我们使用显式类型删除了多态性
还有另一条出路。启用扩展会增加类型默认值的数量,导致
let
表达式比预期的更为单态。在这种情况下,这应该足以恢复共享。如果您尝试(\x->x`seq`x)(fib 30)
和让x=(fib 30)::x`seq`x中的Int
?添加到post中会发生什么,现在更令人惊讶!问题是fib
具有多态类型(orda,numa)=>a->a
。因此,在表达式x`seq`x
中,第一个x
可以被实例化为与第二个x
不同的单态类型。例如,第一个x
可以是Int
,而第二个x
可以是Double
。没有什么能强迫这两个人成为同一类型。这就是为什么要对x
进行两次计算的原因。解决方案很简单。给fib
一个显式的类型签名,比如let fib::Int->Int;fib x=如果x避免了这种性能问题,那么正是引入单态限制的原因。如果没有MR,x
是多态的,x`seq`x
实际上意味着类似于x()`seq`x()
,就好像x
是一个函数,并且seq
将调用该函数两次(可以理解)。
ghci> let f = id in (f True, f 'a')
(True,'a')
ghci> (\f -> (f True, f 'a')) id
*** ERROR ***
fib :: (Ord a, Num a) => a -> a