据我知道的多态seq
功能是不好的,因为它削弱了免费的定理或者,换句话说,一些等式是有效的,而不seq
没有与seq
不再有效。例如,平等
map g (f xs) = f (map g xs)
适用于所有功能g :: tau -> tau'
,所有列表xs :: [tau]
和所有的多态函数f :: [a] -> [a]
。基本上,这种平等说明f
只能对其参数列表的元素重新排序,或者放弃或重复元素,但不能创造新的元素。
说实话,它可以发明元素,因为它可以将非终止计算/运行时错误“插入”到列表中,因为错误类型是多态的。也就是说,在没有seq
的Haskell这种编程语言中,这种平等已经被打破了。下面的函数定义为这个方程提供了一个反例。基本上,在左侧g
“隐藏”错误。
g _ = True
f _ = [undefined]
为了固定该方程中,g
必须是严格的,也就是,它有一个错误映射到一个错误。在这种情况下,平等再次成立。
如果添加多态性seq
运算符,则等式再次中断,例如,以下实例化就是一个反例。
g True = True
f (x:y:_) = [seq x y]
如果我们考虑的名单xs = [False, True]
,我们有
map g (f [False, True]) = map g [True] = [True]
,但是,从另一方面
f (map g [False, True]) = f [undefined, True] = [undefined]
也就是说,你可以使用seq
做出了一定的元素列表的位置取决于列表中另一个元素的定义。如果g
是总数,则等式再次成立。如果您在免费定理intereseted检查了free theorem generator,它允许你指定你是否考虑与错误,甚至有seq
语言的语言。虽然,这似乎是不太实际意义,seq
打破了用于提高的功能程序性能自动,例如,foldr
/build
融合的seq
存在失败一些转换。如果在seq
的存在范围内对有关自由定理的更多细节进行了细分,请查看Free Theorems in the Presence of seq。
据我知道它已经知道,一个多态seq
休息一定的转换,当它被添加到语言。但是,别名也有缺点。如果您添加基于seq
一个类型的类,你可能需要很多类型的类约束添加到您的程序,如果你添加一个seq
某处深跌。此外,它没有被省略seq
因为它已经知道有内存泄露,可以使用seq
固定选择。
最后,我可能会错过某些东西,但我看不到类型的seq
运算符是如何工作的。 seq
的线索是,如果另一个表达式评估为标准形式,则它将评估表达式以标准形式。如果seq
的类型为a -> a
,则无法使一个表达式的评估取决于另一个表达式的评估。
的'seq'函数不是拉姆达可定义(I.R.,不能在λ-演算来定义),这意味着所有的从演算结果可以当我们有'seq'不再值得信任。 – augustss