【问题标题】:Can I coercion be used to generate constraints?我可以使用强制来生成约束吗?
【发布时间】:2018-09-07 22:35:51
【问题描述】:

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

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

这在内部会产生一个 Show aDebug.Trace 系列函数一起使用。

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

【问题讨论】:

  • 您是否尝试过使用ghci debugging 而不是 printf-debugging,或者甚至更好地编写小测试用例来捕获程序逻辑中的错误?
  • GHC 在运行时不保留类型信息:类型在编译期间被擦除。泛型类型a 的参数大致作为无类型指针传递。除了传递/返回它之外,没有其他方法可以使用该参数,因为要访问指向的数据,需要知道它的类型,因此要知道要读取多少字节,以及如何解释它们。
  • 如果您知道运行时类型,即Show 类型,您可以使用不安全强制将该值“强制转换”为运行时类型,之后您可以使用Show。然而,这是一个很大的“如果”。

标签: haskell


【解决方案1】:

不,不可能用您请求的类型和行为实现coerceTraceId

【讨论】:

  • 我很好奇这是否有好的——技术或其他——原因。在我看来,这会很有帮助。
  • @fredefox 是的,chi 在 cmets 中很好地描述了原因。为了提高效率,值的运行时表示不存储有关类型的信息。 False :: BoolLT :: Ordering 在内存中看起来是一样的。因此,不可能“希望”一个Show 实例——甚至不可能“希望”一个正确类型的表示,更不用说下一步为该类型查找Show 字典了。
【解决方案2】:

如果您有足够的胆量忽略 cmets,这就是您真正想做的事情,并演示了如何使用它使 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 -&gt; Int) 实例,GHC 也可以随意忽略它并无论如何都会崩溃。

【讨论】:

  • 您的d 具有单态类型,但问题是关于编写具有多态类型的函数。
  • 对。它实际上不会为不受约束的任意类型 a 生成 Show 实例。
猜你喜欢
  • 1970-01-01
  • 2013-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多