我可以使用强制来产生约束吗?

时间:2018-09-07 09:01:20

标签: haskell

出于调试目的,我想show嵌套在程序逻辑各个部分中的某些值。但是,并非总是如此,我要尝试show的对象有一个Show实例。是否可以以某种方式假设它确实具有有效的实例,并将发生的事件从可能丢失的字典推迟到运行时?我知道我可以在要执行show的函数的上下文中添加约束,这一警告是我可能需要在程序中更改许多签名。我正在寻找类似的功能:

coerceTrace   :: forall a b . a -> b -> b
coerceTraceId :: forall a   . a -> a

这会在内部产生Show a以便与Debug.Trace函数家族一起使用。

我知道我们有unsafeCoerce,但是对我来说,这是否可以用来产生约束条件并不明显。

2 个答案:

答案 0 :(得分:2)

否,无法使用您请求的类型和行为实现coerceTraceId

答案 1 :(得分:0)

如果您足够大胆地忽略注释,那么这就是您想要做的事,并演示了如何使GHCI崩溃。

$ stack install constraints
$ stack ghci
...
> :set -XTypeApplications
> import Data.Constraint
> import Unsafe.Coerce
> d = unsafeCoerce @(Dict (Show Int)) @(Dict (Show (Int -> Int))) Dict
> withDict d $ if False then show (\n -> n + 1 :: Int) else "Success! The Show constraint wasn't needed"
"Success! The Show constraint wasn't needed"
> withDict d $ show (\n -> n + 1 :: Int)
"<interactive>: internal error: PAP object entered!
    (GHC version 8.4.3 for x86_64_unknown_linux)
    Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug
$ # back to shell

免责声明:请勿这样做。即使您在顶级定义了自己的Show (Int -> Int)实例,GHC仍然可以忽略它并使其崩溃。