[GHC] #12708: RFC: Representation polymorphic Num

GHC ghc-devs at haskell.org
Sun Oct 16 18:06:06 UTC 2016


#12708: RFC: Representation polymorphic Num
-------------------------------------+-------------------------------------
        Reporter:  Iceland_jack      |                Owner:
            Type:  feature request   |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Core Libraries    |              Version:  8.0.1
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by Iceland_jack):

 I personally find this beautiful (and it made me think of a solution to
 something I promised to email you a long time ago Richard, correspondence
 is not my strong suit)

 {{{#!hs
 instance P.Num a => Num (a :: Type) where
   (+) :: a -> a -> a
   (+) = (+#)
   -- ...

 instance P.Show a => Show (a :: Type) where
   show :: (a :: Type) -> String
   show = P.show
 }}}

 so I believe this could easily be an “alternate” Prelude, people continue
 to define instances for `Prelude.Num` which makes them instances of our
 runtime-representation polymorphic `Num`.

 A great benefit of `Num` is that I can write

 {{{#!hs
 ten :: Num a => a
 ten = 1 + 2 + 3 + 4
 }}}

 and later define my own type, and it was as if `ten` had been defined with
 it in mind:

 {{{#!hs
 data Exp = I Integer | Exp :+: Exp | ...

 instance Num Exp where
   (+) :: Exp -> Exp -> Exp
   (+) = (:+:)

   fromInteger :: Integer -> Exp
   fromInteger = I

 -- >>> ten :: Exp
 -- ((I 1 :+: I 2) :+: I 3) :+: I 4
 }}}

 Trouble is `ten` must be lifted (`ten :: Prelude.Num a => a`) so we cannot
 pass it to `I#`, but we can write

 {{{#!hs
 reNum :: (forall a. P.Num a => a) -> (forall rep (b :: TYPE rep). Num b =>
 b)
 reNum f =
   fromInteger (f @Integer)

 ten' :: forall rep (a :: TYPE rep). Num a => a
 ten' = reNum ten
 }}}

 which constant folds the rich structure `((I 1 :+: I 2) :+: I 3) :+: I 4`
 into `I 10 :: Exp` but it's fine for `I# (ten' :: Int#)` (which does work
 in HEAD).

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12708#comment:15>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list