[GHC] #14917: Allow levity polymorphism in binding position
GHC
ghc-devs at haskell.org
Fri Aug 17 08:17:58 UTC 2018
#14917: Allow levity polymorphism in binding position
-------------------------------------+-------------------------------------
Reporter: andrewthad | Owner: (none)
Type: feature request | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 8.2.2
Resolution: | Keywords:
| LevityPolymorphism
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 simonpj):
Richard says ''This means that, with your id definition, you couldn't
have''
{{{
idList :: forall a. [a] -> [a]
idList = id
}}}
Yes you could! `idList` is parameterised over a normal always-boxed
type variable, so all its calls will be at boxed types. So `idList` can
call the boxed-a version of `id`. Easy! Template polymorphism is not
infectious. On the contrary, you have to keep specifying it for each
enclosing function.
It's a bit tiresome to have to do this -- it'd be easier for the
programmer to say that ''all'' polymorphism can be specialised in this
way, as .NET does -- but I think that's out of reach for us.
> Generally, these schemes fail on polymorphic recursion, and I think we
should do so here, too.
I don't think so. For `f :: V r. forall (a :: TYPE r). blah` we need one
version of `f` per instantation of `r`. And there are only a finite
number of possiblities for `r` (boxed pointer, unboxed-32-bit,
unboxed-64-bit, etc).
If a function is template-polymorphic in N `RuntimeRep` parameters, then
you could get a number of versions exponential in N, but that's very
pathological.
> Under your "no variables" rule, this List type would have to be
specialized at every possible data parameter. I'm worried about bloat.
I agree. I don't understand this no-variable business. Just one
specialisation per variant of the `RuntimeRep` parameter(s).
> In the end, I think we'd have to implement some deduplication algorithm
during linking
We already have this problem with specialisation. Suppose you say
{{{
module Lib where
f = bah
f :: Num a => a -> a
{-# INLINABLE f #-}
module A where { import Lib; foo = f :: Int -> Int }
module B where { import Lib; bar = f :: Int -> Int }
module C where { import Lib; import A; bax = f :: Int -> Int }
}}}
Then A and B will independently generate a duplicate version of `f`
specialised for `Int -> Int`. But C will not, because it can use the
specialised version it "sees" from A.
So far no one has reported unacceptable bloat.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14917#comment:19>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list