有没有一种方法可以

有没有一种方法可以

TL; DR

有没有一种方法可以用GHC <7.8.1模拟空约束?东西
相似

{-# LANGUAGE NullaryTypeClasses #-}
class HasCallStack
instance HasCallStack

这样
foo :: HasCallStack => Int -> Int

在技​​术上与
foo :: Int -> Int

动机

GHC 8.0.1引入HasCallStack为:
HasCallStack = (?callStack :: CallStack)

对于兼容垫片,我想为所有版本的HasCallStack定义
GHC返回7.0.1

对于支持基于隐式参数调用堆栈的GHC版本,HasCallStack在功能上应与GHC 8.0.1中的等效。

对于不支持基于隐式参数的调用堆栈的GHC版本
(这是GHC的所有版本<7.10.2),HasCallStack应该在功能上
等同于空约束。

为了完整起见,这是仅关注GHC时可以使用的代码7.8.1及更高版本:
#if MIN_VERSION_base(4,8,1)
type HasCallStack = (?callStack :: CallStack)
#else
class HasCallStack
instance HasCallStack
#endif

有没有办法使此功能适用于旧版本的GHC?

作为参考,我将添加当前的解决方案作为答案。但我很想得到
输入其他解决方法。

最佳答案

我不知道有什么方法可以支持我们在GHC中使用的完全相同的语法8.0.1。但是,可以选择使用类型来添加约束
同义词和Rank2Types。以下代码适用于所有版本的GHC
返回7.0.1

#if MIN_VERSION_base(4,8,1)
type HasCallStack a = (?callStack :: CallStack) => a
#else
type HasCallStack a = a
#endif

您问题中的例子
foo :: HasCallStack => Int -> Int

变成
foo :: HasCallStack(Int -> Int)

请注意,这非常可靠。我没有遇到任何无法解决的情况,例如甚至当foo具有其他约束或fooclass方法时,它也可以工作。

07-26 06:49