简体   繁体   English

隐藏 GHC 基础库以防止模式匹配脱糖到 GHC.Num.fromInteger 使用

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM