有没有办法用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?
作为参考,我将添加当前的解决方案作为答案。但我很想得到 输入其他解决方法。
答案 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
有其他约束或foo
是class
方法时使用。