[GHC] #15008: Type synonyms with hidden, determined type variables

#15008: Type synonyms with hidden, determined type variables -------------------------------------+------------------------------------- Reporter: nomeata | Owner: (none) Type: feature | Status: new request | Priority: normal | Milestone: Research needed Component: Compiler | Version: 8.5 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- I found myself wanting to write (simplified) {{{ type MyMonad m = (MonadReader r m, Show r) }}} but GHC does not accept this, it wants `r` as part of the type synonym. So why did I think this could work? Because `MonadReader` has a functional dependency: {{{ class Monad m => MonadReader r m | m -> r }}} so if `m` determines `r`, why do I have to write `MyMonad r m` and not just `MyMonad m`? Can I not “hide” the fact that, somewhere internal to the `MyMonad` synonym, there is an additional variable `r` around? Clearly supporting this would need a language proposal, but I wanted to open a ticket here first to hear if this would even be possible to implement. ([https://stackoverflow.com/questions/29686920/is-it-possible-to-have- forgetful-type-synonyms-in-haskell Others have wanted this before as well.]) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15008 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15008: Type synonyms with hidden, determined type variables -------------------------------------+------------------------------------- Reporter: nomeata | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Research | needed Component: Compiler | Version: 8.5 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 consider this solved by QuantifiedConstraints {{{#!hs a :: (MonadReader r m, Show r) => m String a = fmap show ask }}} becomes {{{#!hs -- A type synonym works but is less useful class (forall xx. (MonadReader xx m, Show xx)) => MyMonad m instance (forall xx. (monadReader xx m, Show xx)) => MyMonad m b :: MyMonad m => m String b = fmap show ask }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15008#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15008: Type synonyms with hidden, determined type variables -------------------------------------+------------------------------------- Reporter: nomeata | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Research | needed Component: Compiler | Version: 8.5 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 nomeata): Ah, nice! This answers the question “is it feasible and implementable?”. It still leaves the question “do we want to provide the convenience of a type synonym to our users” so that they don't have to encode it manually using such a class and an instance. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15008#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15008: Type synonyms with hidden, determined type variables -------------------------------------+------------------------------------- Reporter: nomeata | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Research | needed Component: Compiler | Version: 8.5 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): Did you have something like that in mind? {{{#!hs -- user writes type MyMonad m = (MonadReader r m, Show r) }}} but GHC knows that `r` is determined by `m` so silently {{{#!hs -- GHC transforms it into type MyMonad m = (forall xx. (MonadReader xx m, Show xx)) }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15008#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15008: Type synonyms with hidden, determined type variables -------------------------------------+------------------------------------- Reporter: nomeata | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Research | needed Component: Compiler | Version: 8.5 Resolution: | Keywords: | QuantifiedConstraints, wipT2893 Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by Iceland_jack): * keywords: => QuantifiedConstraints, wipT2893 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15008#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15008: Type synonyms with hidden, determined type variables -------------------------------------+------------------------------------- Reporter: nomeata | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Research | needed Component: Compiler | Version: 8.5 Resolution: | Keywords: | QuantifiedConstraints, wipT2893 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 nomeata): Oh, but now you are using `type`, not a `class`/`instance` pair. Does the `type` work just fine? If that works (with quantified constraints), then I’d be happy, as user, to write {{{ type MyMonad m = (forall r. (MonadReader r m, Show r)) }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15008#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15008: Type synonyms with hidden, determined type variables -------------------------------------+------------------------------------- Reporter: nomeata | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Research | needed Component: Compiler | Version: 8.5 Resolution: | Keywords: | QuantifiedConstraints, wipT2893 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): That works fine unless your example requires partial application (`type instance F = MyMonad`) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15008#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15008: Type synonyms with hidden, determined type variables -------------------------------------+------------------------------------- Reporter: nomeata | Owner: (none) Type: feature request | Status: closed Priority: normal | Milestone: Research | needed Component: Compiler | Version: 8.5 Resolution: worksforme | Keywords: | QuantifiedConstraints, wipT2893 Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by nomeata): * status: new => closed * resolution: => worksforme Comment:
That works fine
That’s good enough for me :-) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15008#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15008: Type synonyms with hidden, determined type variables -------------------------------------+------------------------------------- Reporter: nomeata | Owner: (none) Type: feature request | Status: closed Priority: normal | Milestone: Research | needed Component: Compiler | Version: 8.5 Resolution: worksforme | Keywords: | QuantifiedConstraints, wipT2893 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 AntC): Replying to [comment:3 Iceland_jack]:
{{{#!hs -- GHC transforms it into type MyMonad m = (forall xx. (MonadReader xx m, Show xx)) }}}
The power of `QuantifiedConstraints` seems to get closer to 'magic', the more I see of them! If we didn't have a FunDep on `MonadReader`, could we simulate it with an implication constraint thusly? {{{#!hs -- user writes or GHC transforms it into type MyMonad m = (forall xx. (MonadReader xx m, MonadReader xx m => Show xx)) }}} Would we then need a superclass constraint `Show xx` on `MonadReader xx m`? Or would it be sufficient if the instances were for types in `Show`? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15008#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC