Haskell 基于类约束的Fire重写规则
我正在尝试编写一个Haskell 基于类约束的Fire重写规则,haskell,Haskell,我正在尝试编写一个maybeShow函数,它是show,但没有show类约束。以下是我的尝试: {-# INLINE [1] maybeShow #-} maybeShow :: a -> Maybe String maybeShow _ = Nothing canShow :: Show a => a -> Maybe String canShow = Just . show data CantShow = CantShow main = do print (may
maybeShow
函数,它是show
,但没有show
类约束。以下是我的尝试:
{-# INLINE [1] maybeShow #-}
maybeShow :: a -> Maybe String
maybeShow _ = Nothing
canShow :: Show a => a -> Maybe String
canShow = Just . show
data CantShow = CantShow
main = do
print (maybeShow (42 :: Int))
print (maybeShow CantShow)
{-# RULES
"maybeShow" forall (x :: (Show a => a)). maybeShow x = canShow x
#-}
但在这段代码中,重写规则似乎从未启动过
我知道对于可显示的类型,有时会返回Nothing
。例如,我完全希望在非内联函数中使用maybeShow
,而这些函数不是专门针对特定类型的函数,可以返回Nothing
。但是,当我使用maybeShow
作为添加到error
输出中的内容时,如果它不总是起作用,这其实并不重要
但我希望它有时能工作(例如,当它被内联到调用函数中时),而不是像现在这样永远不能工作
关于如何启动重写规则有什么想法吗?这表明它是可以做到的,但是这个建议可以追溯到GHC 6.6,所以我不确定它是否仍然有效。我仍然不清楚这些要求,但除了以下两个,我想不出其他解决方案,例如,通过跟踪参数类型的跟踪值来调试多态函数库,但添加
Show
约束将破坏下游代码
对单态类型使用重写规则。我假设出于调试目的,您只需要几个类型。然而,这可能相当不可靠,您可能需要明确地专门化/内联函数
也许您可以使用另一个类型类和一个可重叠的实例
class MaybeShow a where
maybeShow :: a -> Maybe String
instance {-# OVERLAPPABLE #-} MaybeShow a where
maybeShow _ = Nothing
然后有选择地将其专门化为用于调试的少数类型
instance MaybeShow Int where
maybeShow n = Just (show n)
但是,您仍然需要为使用它的每个函数添加一个MaybeShow
约束
在这里,您可以经常使用PartialTypeSignatures
编写更简洁的顶级签名
myFun :: _ => a -> w a
constrainedFun :: (_, RealConstraint a) => a -> b a
但是,这种方法的优点是行为更加可预测。我认为您不能有条件地对实例的存在触发规则,因为正如您链接到的页面所示,规则在字典展开后应用,然后变成简单的语法检查。你能解释一下你想做什么吗?显示变量以进行调试(即在“错误”调用中),而不需要显示约束。