在 GHC 中,有没有办法在运行时确定一个抽象值是否是一个函数?
Is there a way to determine at runtime, in GHC, whether an abstract value is a function?
我想知道是否有可能有一个功能(有点类似于dataToTag#
)像:
isFunction# :: a -> Bool
或可能等效地:
isFunction# :: Any -> Bool
which returns True
iff 作为参数传入的值在运行时是 a -> b
类型(或者,就此而言,a => b
)类型 a
和 b
,或者一个 newtype
其基础类型是(所以它是 "sees through" newtype
s,但当然不是 data
),没有强迫它的论点。我自己在 GHC.Prim 中没有看到类似的东西,但我可能漏掉了一些东西,或者可能使用手动 CMM primop 或其他东西。
既然我想到了这个问题,我很好奇它本身的答案 (question Y),但我想到这个问题(问题 X)的最初原因是投诉通常会平息反对 seq
的是它通过观察 undefined
和 \_ -> undefined
之间的差异打破了 eta 等价性,我想知道是否有可能制作 [=21] 的一个版本=] (myseq a = if isFunction# a then flip const a else seq a
) 仍然是 "magically polymorphic"(有效 forall a
),但只是单独保留函数。
不,肯定不是。不评估参数怎么知道?
但是为了直接解决你的问题 X,你提出的 myseq
比真正的 seq
更糟糕,因为它破坏了参数化。是myseq undefined :: b -> b
底,还是身份?这取决于类型变量 a
(undefined :: a
) 是否使用函数类型实例化。
在 Haskell 中,当 a
根本没有出现在类型中时,您总是可以删除 forall a.
,这要归功于参数化:a
的选择没关系。你的 myseq
会失去那个 属性.
这也是为什么如果不在运行时用预期类型注释值就无法实现 isFunction#
(isFunction# undefined
同样没有意义)。
我想知道是否有可能有一个功能(有点类似于dataToTag#
)像:
isFunction# :: a -> Bool
或可能等效地:
isFunction# :: Any -> Bool
which returns True
iff 作为参数传入的值在运行时是 a -> b
类型(或者,就此而言,a => b
)类型 a
和 b
,或者一个 newtype
其基础类型是(所以它是 "sees through" newtype
s,但当然不是 data
),没有强迫它的论点。我自己在 GHC.Prim 中没有看到类似的东西,但我可能漏掉了一些东西,或者可能使用手动 CMM primop 或其他东西。
既然我想到了这个问题,我很好奇它本身的答案 (question Y),但我想到这个问题(问题 X)的最初原因是投诉通常会平息反对 seq
的是它通过观察 undefined
和 \_ -> undefined
之间的差异打破了 eta 等价性,我想知道是否有可能制作 [=21] 的一个版本=] (myseq a = if isFunction# a then flip const a else seq a
) 仍然是 "magically polymorphic"(有效 forall a
),但只是单独保留函数。
不,肯定不是。不评估参数怎么知道?
但是为了直接解决你的问题 X,你提出的 myseq
比真正的 seq
更糟糕,因为它破坏了参数化。是myseq undefined :: b -> b
底,还是身份?这取决于类型变量 a
(undefined :: a
) 是否使用函数类型实例化。
在 Haskell 中,当 a
根本没有出现在类型中时,您总是可以删除 forall a.
,这要归功于参数化:a
的选择没关系。你的 myseq
会失去那个 属性.
这也是为什么如果不在运行时用预期类型注释值就无法实现 isFunction#
(isFunction# undefined
同样没有意义)。