[Haskell] Rank-N types with (.) composition
Simon Peyton Jones
simonpj at microsoft.com
Wed Feb 11 09:39:31 UTC 2015
($) has its own *typing rule*; it does not have a special type. It's very ad hoc, but ($) is used so much to decrease parens that (e1 $ e2) is almost special syntax!
At the moment the *only* robust way to pass a polymorphic function to a polymorphic function (here, you are passing Wrap to (.)) is to wrap it in a newtype, much as Wrap does.
I have made several forays into the impredicative swamp, and barely made it back to the shore alive. I think that, at least in the context of Haskell, the trick is to be less ambitious, something like QML.
Since this comes up regularly, I've started a wiki page to explain the issues:
https://ghc.haskell.org/trac/ghc/wiki/ImpredicativePolymorphism
Please do improve it.
Simon
| -----Original Message-----
| From: Haskell [mailto:haskell-bounces at haskell.org] On Behalf Of Tyson
| Whitehead
| Sent: 10 February 2015 23:20
| To: Dan Doel
| Cc: haskell at haskell.org
| Subject: Re: [Haskell] Rank-N types with (.) composition
|
| On February 10, 2015 16:28:56 Dan Doel wrote:
| > Impredicativity, with regard to type theories, generally refers to
| > types being able to quantify over the collection of types that they
| > are then a part of. So, the judgment:
| >
| > (forall (a :: *). a -> a) :: *
| >
| > is impredicative, because we have a type in * that quantifies over
| all
| > types in *, which includes itself. Impredicativity in general refers
| > to this sort of (mildly) self-referential definition.
|
| Thanks Dan and David,
|
| That was informative. Also very interesting that ($) is a special
| case. I tried this
|
| newtype Wrap = Wrap { extract :: forall f. Functor f => f Int }
|
| trip'' :: Wrap -> Wrap
| trip'' a = Wrap $ extract a
|
| and the compiler was happy. Wrapping ($) as ($') gave an error as you
| implied it would
|
| trip''' :: Wrap -> Wrap
| trip''' a = Wrap $' extract a
| where ($') = ($)
|
| With regard to my earlier comment about translating the (.) version
|
| trip' :: Wrap -> Wrap
| trip' = Wrap . extract
|
| to core, I can see it's actually okay. A most you may need is a
| lambda to float the implicit parameters backwards
|
| trip' :: Wrap -> Wrap
| trip' = Wrap . (\a f fDict -> extract f fDict a)
|
| as GHC seems to always float them as far leftward as possible
|
| extract :: Functor f => Wrap -> f Int
|
| I take it there are no user supplied types a person can give to
| overcome the predicative assumption?
|
| Out of curiosity, how would you write the special internal type that
| ($) has that separates it from ($') above?
|
| Thanks! -Tyson
| _______________________________________________
| Haskell mailing list
| Haskell at haskell.org
| http://www.haskell.org/mailman/listinfo/haskell
More information about the Haskell
mailing list