我尝试编写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
输出的内容时,如果它不能始终有效,那么它并不重要。
但我希望它有时可以工作(例如,当它被内联到调用函数中时),而不是现在似乎没有。
有关如何启动重写规则的任何想法? wiki.haskell.org上的这个建议可以做到,但建议可以追溯到GHC 6.6,所以我不确定它是否仍然有效。
答案 0 :(得分:0)
我的要求仍然不明确,但我无法想到其他解决方案而不是以下两个解决方案,例如,通过跟踪参数类型的跟踪值调试多态函数库,但添加{{1约束会破坏下游代码。
对单形类型使用重写规则。我假设出于调试目的,您只需要几种类型。但是,这可能相当不可靠,您可能需要明确地专门化/内联函数。
也许你可以使用另一个带有覆盖可覆盖实例的类型。
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
然而,这种方法具有更具可预测性的优点。