[GHC] #12708: RFC: Representation polymorphic Num

GHC ghc-devs at haskell.org
Sun Jan 29 05:14:00 UTC 2017


#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:
                                     |  LevityPolymorphism
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:  #12980            |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by goldfire):

 An exhaustive search through `ghc-prim` and `base` found 34 (!) classes
 that can be generalized this way:

 {{{
 Eq, Ord, Functor, Applicative, Monad, MonadFail, MonadFix, MonadIO,
 Bifoldable, Bifunctor, HasResolution, Foldable, Eq1, Ord1, Eq2, Ord2,
 IsString, TestCoercion, TestEquality, Storable, IsList, Num, Real,
 Fractional, Generic, Generic1, GHCiSandboxIO, BufferedIO, RawIO,
 IsLabel, PrintfType, HPrintfType, PrintfArg, IsChar
 }}}

 Some are surely more useful to generalize than others. But wow!

 More classes morally could be included in this list but for two limiting
 factors:
  - Many classes use lists somewhere. (For example, `Show`.) However, we
 could define a family of list types, one for each representation (which
 would box unboxed tuples), and then use a type family to select the
 appropriate list type, allowing generalizations of classes that use lists.
  - Several classes (e.g., `Integral`) use tuples, preventing
 generalization. But we could just use unboxed tuples and away we go.

 Another annoyance was that `Applicative` can be generalized to make its
 parameter `f :: Type -> TYPE r`, but not `f :: TYPE r1 -> TYPE r2`. The
 latter is impossible because the class definition mentions `f (a -> b)`,
 and functions are always lifted.

 It would be lovely, though, to ponder the possibility of `class
 Applicative (f :: forall (r1 :: RuntimeRep). TYPE r1 -> TYPE r2)`, where
 `Applicative` would then have a higher-rank kind. And, we could generalize
 `IO` (it's implemented using an unboxed tuple, after all) and then `IO`
 could be made an instance of this new `Applicative`. `Monad` would soon
 follow, and you'd then be able to return unboxed values in `do`-notation.

 A final note: In testing all this, I had to add `default` signatures
 imposing a `r ~ LiftedRep` constraint whenever a generalized class had a
 default implementation, because the default implementation would work only
 at kind `Type`. This works, but it's disappointing that there can be no
 defaults at representations other than `LiftedRep`. However, I've realized
 we ''can''. Instead of `r ~ LiftedRep` in the `default` signature, impose
 a `Typeable r` constraint. Then we can do a runtime type test to figure
 out the representation and to squash the levity polymorphism. (This
 actually works.) A sufficiently smart compiler would be able to optimize
 away the runtime type test in any non-levity-polymorphic class instance.
 And we're just left with happiness and a wicked powerful type system.

 My (rushed, somewhat shoddy) work on this is
 [https://github.com/goldfirere/ghc/tree/lev-poly-base here]. I don't
 expect that to ever be merged -- I just was exploring the possibility.

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


More information about the ghc-tickets mailing list