[GHC] #9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types

#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: spacekitteh | Owner: Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: Keywords: | Operating System: Architecture: Unknown/Multiple | Unknown/Multiple Difficulty: Moderate (less | Type of failure: than a day) | None/Unknown Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- Say I have a class like the following: {{{#!hs class IntLike a where fromInt :: Int -> a toInt :: a -> Int }}} There should be a typesafe, principled way to get the dictionary type created from buildClass in compiler/iface/BuildTyCl.lhs like such (in this hypothetical, using a type family: {{{#!hs plusN :: (IntLike a) => Int -> Dictionary (IntLike a) }}} It would be nice if the type family was injective, if it was implemented in such a way. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: | Owner: spacekitteh | Status: new Type: feature | Milestone: request | Version: Priority: normal | Keywords: Component: Compiler | Architecture: Unknown/Multiple Resolution: | Difficulty: Moderate (less Operating System: | than a day) Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by goldfire): I'm sorry, but I don't understand your request. The dictionary for `IntLike` would look something like this: {{{ data IntLikeDict a = MkIntLikeDict { fromInt :: Int -> a ; toInt :: a -> Int } }}} There isn't an actual number stored anywhere. And, in fact, my example has made things more complicated than they really are. The dictionary type within GHC '''is''' `IntLike` -- there's no separate dictionary type. Is `Dict` what you're looking for? {{{ data Dict c where Dict :: c => Dict c }}} That's definable today with !ConstraintKinds. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: | Owner: spacekitteh | Status: new Type: feature | Milestone: request | Version: Priority: normal | Keywords: Component: Compiler | Architecture: Unknown/Multiple Resolution: | Difficulty: Moderate (less Operating System: | than a day) Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by spacekitteh): "I'm sorry, but I don't understand your request. The dictionary for IntLike would look something like this: data IntLikeDict a = MkIntLikeDict { fromInt :: Int -> a ; toInt :: a -> Int } There isn't an actual number stored anywhere. And, in fact, my example has made things more complicated than they really are. The dictionary type within GHC is IntLike -- there's no separate dictionary type." Yeah, I know, I just thought it would be obvious that I meant like, prependending the from/toInts with a lambda involving the first argument. Does the Dict method grant you access to the fromInt/toInt methods for each type? I.e. can you obtain, say, an IntLikeDict [Char] containing the functions? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: | Owner: spacekitteh | Status: new Type: feature | Milestone: request | Version: Priority: normal | Keywords: Component: Compiler | Architecture: Unknown/Multiple Resolution: | Difficulty: Moderate (less Operating System: | than a day) Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by goldfire): I'm not sure what you mean by "grant access"... but perhaps this will help: When you pattern match on the `Dict` constructor, you get the `c` constraint in the context. So, the following is conceivable: {{{ -- this type is actually from ekmett's "constraints" package data Dict c where Dict :: c => Dict c class IntLike a where fromInt :: Int -> a toInt :: a -> Int dictForIntLikeString :: Dict (IntLike String) dictForIntLikeString = ... stringToInt :: String -> Int stringToInt s = case dictForIntLikeString of Dict -> toInt s }}} Note that there is no `instance IntLike String` around -- the reason `toInt` can be called in `stringToInt` is because of the pattern-match on `Dict`. Now, this example falls apart because the implementation of `dictForIntLikeString` seems impossible without a `instance IntLike String` dictionary available. But perhaps this answers your question about what `Dict` can do. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: | Owner: spacekitteh | Status: new Type: feature | Milestone: request | Version: Priority: normal | Keywords: Component: Compiler | Architecture: Unknown/Multiple Resolution: | Difficulty: Moderate (less Operating System: | than a day) Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by spacekitteh): Essentially, I'm looking for a method to automate the process of defining the Def data function in the ReifiableConstraint class in here: https://www.fpcomplete.com/user/thoughtpolice/using-reflection#turning-up- the-magic-to-over-9000 for arbitrary constraints. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: | Owner: spacekitteh | Status: new Type: feature | Milestone: request | Version: Priority: normal | Keywords: Component: Compiler | Architecture: Unknown/Multiple Resolution: | Difficulty: Moderate (less Operating System: | than a day) Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by goldfire): OK -- so it seems you want to be able to fuzz the `*`/`Constraint` distinction. That is, for example, make explicit dictionaries of `Show` and pass them as parameters to functions with a declared `Show` constraint. Another way to think about this is that you want the ability to define local instances, much like what is done in that blog post. The problem here is that local instances threaten coherence properties. Local instances are really useful, but I think a fair amount of design work needs to be done to integrate local instances with Haskell. Or, simply to automate building `Def` instances, I would suggest Template Haskell. Without a general plan toward local instances, it seems too specific to bake in deriving `Def` instances into GHC, when it can easily be done with TH. [https://groups.google.com/forum/#!msg/haskell- cafe/JR8qd6RBKW4/xDcdtmuE9gsJ This haskell-cafe thread] may be of interest. It explores some of this design space. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: | Owner: spacekitteh | Status: new Type: feature | Milestone: request | Version: Priority: normal | Keywords: Component: Compiler | Architecture: Unknown/Multiple Resolution: | Difficulty: Moderate (less Operating System: | than a day) Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by spacekitteh):
OK -- so it seems you want to be able to fuzz the */Constraint distinction.
Sorta, yeah. More like having a data type of existential functions. I'm actually trying to work towards local instances (or at least, better library support for approximations of it like reflection). As such it is inappropriate for TH. Additionally, I wish for it to run on platforms without TH, such as ARM. I'm not really proposing a general language feature, but rather, allowing typesafe access to desugared syntax; any high level language design would almost certainly need access to it anyway, so this would be laying the foundation for experimentation in that area. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: | Owner: spacekitteh | Status: new Type: feature | Milestone: request | Version: Priority: normal | Keywords: Component: Compiler | Architecture: Unknown/Multiple Resolution: | Difficulty: Moderate (less Operating System: | than a day) Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by spacekitteh): It seems like the converse of that thread though - it's more wanting to be able to say "use this dictionary to evaluate this function" without having to manually create a new datatype etc. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: | Owner: spacekitteh | Status: new Type: feature | Milestone: request | Version: Priority: normal | Keywords: Component: Compiler | Architecture: Unknown/Multiple Resolution: | Difficulty: Moderate (less Operating System: | than a day) Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by goldfire): But, if you had local instances, then there wouldn't be just one, say, `Ord Int` out there. There would be the global one, and potentially many local ones. It now becomes very confused to try to use a `Set Int`, when the `Ord Int` instance might be changing. I'm not saying that local instances are Wrong, but that they require a fair amount of design work before we can begin to think about implementing. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: | Owner: spacekitteh | Status: new Type: feature | Milestone: request | Version: Priority: normal | Keywords: Component: Compiler | Architecture: Unknown/Multiple Resolution: | Difficulty: Moderate (less Operating System: | than a day) Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by spacekitteh): Right. I'm not requesting local instances as a whole; rather, just access to the desugared typeclass dictionary types. Basically, adding a Dictionary kind, and a type function from Constraint kinds to Dictionary kinds (local instances could involve adding a type function in the reverse direction). -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: | Owner: spacekitteh | Status: new Type: feature | Milestone: request | Version: Priority: normal | Keywords: Component: Compiler | Architecture: Unknown/Multiple Resolution: | Difficulty: Moderate (less Operating System: | than a day) Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by spacekitteh): Upon perusing the dictionary creation source some more, it appears that it could be implemented by changing adding a flag to {{{ mkClassDataConOcc = mk_simple_deriv dataName "D:" -- We go straight to the "real" data con -- for datacons from classes }}} in compiler/basicTypes/OccName.hs like so {{{ mkClassDataConOcc True = mk_simple_deriv dataName "" mkClassDataConOcc False = mk_simple_deriv dataName "D:" }}} and change buildClass in compiler/iface/BuildTyCl.hs from: {{{ ... ; datacon_name <- newImplicitBinder tycon_name mkClassDataConOcc }}} to {{{ ; datacon_name <- newImplicitBinder tycon_name (mkClassDataConOcc visibleConstructor) }}} This would require modifying buildClass to accept DynFlags, though. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

Right. I'm not requesting local instances as a whole; rather, just access to the desugared typeclass dictionary types. Basically, adding a Dictionary kind, and a type function from Constraint kinds to Dictionary kinds (local instances could involve adding a type function in the reverse
#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: | Owner: spacekitteh | Status: new Type: feature | Milestone: request | Version: Priority: normal | Keywords: Component: Compiler | Architecture: Unknown/Multiple Resolution: | Difficulty: Moderate (less Operating System: | than a day) Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by goldfire): Replying to [comment:9 spacekitteh]: direction). Additionally, a Coercible instance for the class and the dictionary would be useful too.
This seems like it would be fairly straightforward to implement and not
involve much design work; the problems seem to only arise when going from Dictionary -> Constraint. Ah. This makes sense. But, before diving into implementation, we need a clear specification of the feature, preferably on a wiki page. The page should contain motivation and examples of programs that you wish to be accepted. Then, we'll all have a better idea of what we're discussing. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: | Owner: spacekitteh | Status: new Type: feature | Milestone: request | Version: Priority: normal | Keywords: Component: Compiler | Architecture: Unknown/Multiple Resolution: | Difficulty: Moderate (less Operating System: | than a day) Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by spacekitteh): (Sorry for not being very clear; I'm autistic) I'll get to work on a wiki page I guess. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819#comment:12 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: | Owner: spacekitteh | Status: new Type: feature | Milestone: request | Version: Priority: normal | Keywords: Component: Compiler | Architecture: Unknown/Multiple Resolution: | Difficulty: Moderate (less Operating System: | than a day) Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by spacekitteh): https://ghc.haskell.org/trac/ghc/wiki/DesugaredDictionaries -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819#comment:13 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: | Owner: spacekitteh | Status: new Type: feature | Milestone: request | Version: Priority: normal | Keywords: Component: Compiler | Architecture: Unknown/Multiple Resolution: | Difficulty: Moderate (less Operating System: | than a day) Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by simonpj): Thanks. I have not been following the thread in detail, because I've been hoping it would reach a conclusion in the form of a wiki page summarising the proposal. Thank you for making a start on it. But I can't understand it (yet) I'm afraid. Could you have a go at clarifying. In particular: * What, precisely, IS the proposal? Perhaps you can add a section heading "The proposal" that says, as precisely as possible, what the changes (from the point of view of the user) are. Is there any new syntax? Are there any new system-provided functions? Does type inference change? (For example, the wiki page mentions `using`, but I have no idea what it is.) * You could have a sub-section "What this proposal is NOT", covering the bit about overlapping instances. * Several examples of using the new facility. Again a section "Examples of use". * Then (and only then) some discussion about implementation. Thanks. Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819#comment:14 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: | Owner: spacekitteh | Status: new Type: feature | Milestone: request | Version: Priority: normal | Keywords: Component: Compiler | Architecture: Unknown/Multiple Resolution: | Difficulty: Moderate (less Operating System: | than a day) Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by spacekitteh): Thanks for the advice. It'll come together slowly, I'm afraid; writing isn't exactly my strong point. I'll get working on it! -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819#comment:15 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: | Owner: spacekitteh | Status: new Type: feature | Milestone: request | Version: Priority: normal | Keywords: Component: Compiler | Architecture: Unknown/Multiple Resolution: | Difficulty: Moderate (less Operating System: | than a day) Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by spacekitteh): I've improved the wiki page a bit; hopefully it's clearer now @simonpj -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819#comment:16 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: | Owner: spacekitteh | Status: new Type: feature | Milestone: request | Version: Priority: normal | Keywords: Component: Compiler | Architecture: Unknown/Multiple Resolution: | Difficulty: Moderate (less Operating System: | than a day) Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by simonpj): I'm concentrating on the section "Base proposal". It says "Expose the constructor of the dictionary datatype created by desugaring typeclasses". But what does that mean? * Is there any new syntax? If so what, precisely? * Are there any new types available? How are they declared and used? * Are there any new functions available? If so which, and with what types? * Does type inference change at all? If so how? * Could you give some examples of usage? I know it's hard, but you can't define a language feature in one paragraph! Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819#comment:17 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9819: Create typesafe method of obtaining dictionary types from class definitions, and constraint objects from dictionary types -------------------------------------+------------------------------------- Reporter: | Owner: spacekitteh | Status: new Type: feature | Milestone: request | Version: Priority: normal | Keywords: Component: Compiler | Architecture: Unknown/Multiple Resolution: | Difficulty: Moderate (less Operating System: | than a day) Unknown/Multiple | Blocked By: Type of failure: | Related Tickets: None/Unknown | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by spacekitteh): Sorry, I had much of the information in there but it was scattered. The page is still a WIP. I updated it again to hopefully be in a more readable format. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9819#comment:18 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC