haskell序曲:seq的定义

Mic*_*ser 2 haskell

haskell前奏定义中,我们看到它...是为无法在Haskell中实现的表达式保留的.现在IOmonad例如无法在haskell中实现.

让我感到惊讶的是seq前奏中定义如下

seq :: a -> b -> b
seq = ...       -- Primitive
Run Code Online (Sandbox Code Playgroud)

为什么不以下?我错过了什么?

seq _ b = b
Run Code Online (Sandbox Code Playgroud)

Man*_*erl 6

正如您在Haskell Wiki条目seq中所看到的,该seq函数必须满足以下两个等式:

? `seq` b = ?
a `seq` b = b
Run Code Online (Sandbox Code Playgroud)

(其中?是未定义的值,这是非终止函数应用程序或类似的东西,hd []undefined在逻辑上评估)

您的定义显然不符合第一个等式.

典型的用例seq是在评估第二个参数之前强制评估第一个参数(到弱头正常形式).(严格来说,seq不保证;再看维基文章)

据我所知,这样的函数在没有任何编译器扩展的纯Haskell中是不可定义的-XBangPatterns.

  • @ sdx23通常情况并非如此:Haskell中的`case`不能强制使用函数值表达式(与GHC Core不同,`case`确实评估).你可以通过对构造函数的模式匹配为所有代数数据类型定义一个类似seq`的函数:对于那个`case`来说确实足够了. (2认同)