有没有办法用GHC<语法模拟空约束? 7.8.1?

时间:2016-04-02 04:37:31

标签: haskell types ghc

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?

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

1 个答案:

答案 0 :(得分:4)

我不知道有任何方法可以支持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方法时使用。