I have created a replacement Prelude for use in teaching beginning Haskell students, called 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. 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:
isZero 0 = True
isZero _ = False
If I ask GHCi for the type, I get:
isZero :: (GHC.Classes.Eq a, GHC.Num.Num a) => a -> Bool
But what I want is to get Integer -> Bool
. Dumping the simplified core out of GHC I can see it is using:
(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. Is there a way I can somehow prevent GHC.Num.fromInteger
from being used? I guess perhaps this possible at the package level, but really I would love this at the module level for other pedagogical reasons.
This is not tied to pattern matching: In your Example.hs
, even literals in expressions are polymorphic. 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.
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. You can do that in the .cabal
file, maybe good enough for your educational needs.