[英]Hide GHC base library to prevent pattern matching desugaring to GHC.Num.fromInteger use
I have created a replacement Prelude for use in teaching beginning Haskell students, called FirstPrelude .我创建了一个替代 Prelude 用于教学 Haskell 名学生,称为FirstPrelude 。 One of the aims is to expunge type classes from the standard library so that error messages are more of the classic Hindley-Milner variety, rather than getting
No instance
errors.目标之一是从标准库中删除类型类,以便错误消息更多地是经典的 Hindley-Milner 类型,而不是得到
No instance
错误。 This is working out quite well.这很有效。 However, something I did not anticipate is that, when pattern matching, GHC is side-stepping my redefinition of
fromInteger
(defined as the identity, monomorphised to only work on Integer
) and so for example, with this function:然而,我没有预料到的是,当模式匹配时,GHC 回避了我对
fromInteger
的重新定义(定义为身份,单态化仅适用于Integer
),例如,对于这个 function:
isZero 0 = True
isZero _ = False
If I ask GHCi for the type, I get:如果我向 GHCi 询问类型,我会得到:
isZero :: (GHC.Classes.Eq a, GHC.Num.Num a) => a -> Bool
But what I want is to get Integer -> Bool
.但我想要的是获得
Integer -> Bool
。 Dumping the simplified core out of GHC I can see it is using:从 GHC 中转储简化的核心,我可以看到它正在使用:
(GHC.Num.fromInteger @Integer GHC.Num.$fNumInteger 0)))
I would have thought it would just use my fromInteger:: Integer -> Integer
that is in scope, but alas no.我本以为它只会使用我的
fromInteger:: Integer -> Integer
中的 Integer,但可惜没有。 Is there a way I can somehow prevent GHC.Num.fromInteger
from being used?有没有办法以某种方式阻止
GHC.Num.fromInteger
被使用? I guess perhaps this possible at the package level, but really I would love this at the module level for other pedagogical reasons.我想这可能在 package 级别,但出于其他教学原因,我真的很喜欢模块级别。
This is not tied to pattern matching: In your Example.hs
, even literals in expressions are polymorphic.这与模式匹配无关:在您的
Example.hs
中,即使表达式中的文字也是多态的。 To see this, write something like要看到这个,写一些像
simpler :: ()
simpler = 1
and observe the error message并观察错误信息
[2 of 2] Compiling Main ( Example.hs, interpreted )
Example.hs:7:11: error:
• No instance for (GHC.Num.Num ()) arising from the literal ‘1’
• In the expression: 1
In an equation for ‘simpler’: simpler = 1
|
7 | simpler = 1
| ^
Failed, one module loaded.
You may not have noticed because as soon as you use one of “your” operations, GHC specializes the type, and for top-level values may use defaulting.您可能没有注意到,因为一旦您使用“您的”操作之一,GHC 就会专门化类型,并且对于顶级值可能会使用默认值。
But note但请注意
simpler _ = 1
for which it infers this type它推断出这种类型
ghci> :t simpler
simpler :: GHC.Num.Num p1 => p2 -> p1
If you enable {-# LANGUAGE RebindableSyntax #-}
, it really uses “your” fromInteger
and things work as you expect.如果您启用
{-# LANGUAGE RebindableSyntax #-}
,它实际上使用“您的” fromInteger
并且一切如您所愿。 You can do that in the .cabal
file, maybe good enough for your educational needs.您可以在
.cabal
文件中执行此操作,这可能足以满足您的教育需求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.