我已经创建了一个替代的Prelude,用于教授Haskell的初学者,名为FirstPrelude。目标之一是从标准库中删除类型类,以便错误消息更像是经典的Hindley-Milner类型,而不是No instance
错误。这非常有效。但是,我没有预料到的是,当模式匹配时,GHC绕过了我对fromInteger
的重新定义(定义为恒等式,单态化为只对Integer
有效),因此,例如,使用以下函数:
isZero 0 = True
isZero _ = False
如果我问GHCi类型,我得到:
isZero :: (GHC.Classes.Eq a, GHC.Num.Num a) => a -> Bool
但是我想要的是得到Integer -> Bool
。从GHC中转储简化的核心,我可以看到它使用:
(GHC.Num.fromInteger @Integer GHC.Num.$fNumInteger 0)))
我本以为它只会使用我的fromInteger :: Integer -> Integer
,但可惜没有。有什么方法可以阻止GHC.Num.fromInteger
被使用吗?我想这在包级别上可能是可能的,但出于其他教学原因,我真的希望在模块级别上这样做。
1条答案
按热度按时间lpwwtiir1#
这与模式匹配无关:在
Example.hs
中,表达式中的文字也是多态的。并观察错误消息
您可能没有注意到,因为只要您使用“您的”操作之一,GHC就会专门化该类型,并且对于顶级值可能使用默认值。
但是注意
它会推断出这种类型
如果你启用了
{-# LANGUAGE RebindableSyntax #-}
,它就真的使用了你的fromInteger
,一切都如你所愿。你可以在.cabal
文件中这样做,也许足够满足你的教育需求了。