{"action":"opened","issue":{"url":"https://api.github.com/repos/purescript/purescript/issues/3413","repository_url":"https://api.github.com/repos/purescript/purescript","labels_url":"https://api.github.com/repos/purescript/purescript/issues/3413/labels{/name}","comments_url":"https://api.github.com/repos/purescript/purescript/issues/3413/comments","events_url":"https://api.github.com/repos/purescript/purescript/issues/3413/events","html_url":"https://github.com/purescript/purescript/issues/3413","id":350373994,"node_id":"MDU6SXNzdWUzNTAzNzM5OTQ=","number":3413,"title":"Question: type-level records?","user":{"login":"chrisdone","id":11019,"node_id":"MDQ6VXNlcjExMDE5","avatar_url":"https://avatars3.githubusercontent.com/u/11019?v=4","gravatar_id":"","url":"https://api.github.com/users/chrisdone","html_url":"https://github.com/chrisdone","followers_url":"https://api.github.com/users/chrisdone/followers","following_url":"https://api.github.com/users/chrisdone/following{/other_user}","gists_url":"https://api.github.com/users/chrisdone/gists{/gist_id}","starred_url":"https://api.github.com/users/chrisdone/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chrisdone/subscriptions","organizations_url":"https://api.github.com/users/chrisdone/orgs","repos_url":"https://api.github.com/users/chrisdone/repos","events_url":"https://api.github.com/users/chrisdone/events{/privacy}","received_events_url":"https://api.github.com/users/chrisdone/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-08-14T10:42:42Z","updated_at":"2018-08-14T10:42:42Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"Has anyone considered adding support to use record syntax at the type-level?\r\n\r\nFor example:\r\n\r\n```haskell\r\ndata Component (h :: Type -> Type -> Type) (f :: Type -> Type) i o (m :: Type -> Type)\r\n```\r\n\r\n> h is the type that will be rendered by the component, usually HTML\r\n>f is the query algebra\r\n>i is the input value type that will be mapped to an f whenever the parent of this component renders\r\n>o is the type for the component's output messages\r\n>m is the monad used for non-component-state effects\r\n\r\nThis comes from Halogen. I have a similar problem with Duet, my small Haskell compiler. How do we make types like this more readable? I'd like to be able to write e.g.: (making up random syntax)\r\n\r\n```haskell\r\ndata Component <surface, query, input, output, monad>\r\n```\r\n\r\nSo then instead of types looking like these:\r\n\r\n```haskell\r\nmyButton :: forall m. H.Component HH.HTML Query Unit Message m\r\n\r\neval :: Query ~> H.ComponentDSL State Query Message m\r\n```\r\n\r\nit'd look like:\r\n\r\n```haskell\r\nmyButton :: forall m. \r\n  H.Component<surface: HH.HTML, query: Query, input: Unit, output: Message, monad: m>\r\n\r\neval :: Query ~> H.ComponentDSL<state: State, query: Query, output: Message, monad: m>\r\n```\r\n\r\nThe same kind of thing applies to e.g. conduit from Haskell world.\r\n\r\n\r\n-------\r\n\r\nIncidentally it could have interesting applications for type-classes:\r\n\r\n```haskell\r\ndata Either<left, right> = Left left | Right right\r\n```\r\nand then you could partially apply to re-use existing positional class instances, to make an instance of Functor on the Left of an Either (not for a good reason, but they exist):\r\n\r\n```haskell\r\ninstance Functor Either<right> where\r\n  fmap f (Left a) = Left (f a)\r\n  fmap _ (Right c) = Right c\r\n```\r\nor otherwise be radical and invent class instances which let you specify the parameters:\r\n```haskell\r\nclass Functor t<element | r> where\r\n fmap :: forall a b. (a -> b) -> t<element: a | r> -> t<element: b | r>\r\n\r\ninstance Functor Either<left=element|r> where ...\r\n\r\nclass Bifunctor t<first, second | r> where\r\n first  :: forall a b. (a -> b) -> t<first: a | r> -> t<first: b | r>\r\n second :: forall a b. (a -> b) -> t<second: a | r> -> t<second: b | r>\r\n\r\ninstance Functor Either<left=first, right=second|r> where ...\r\n```\r\n-----\r\n\r\nHas there been any discussion or research like this? I feel like PureScript is a step forward in avoiding [complecting](https://www.youtube.com/watch?v=rI8tNMsozo0&t=24m10s) which we suffer from in Haskell at the value level, but at the type-level it can be a bit lacking. "}}
{"actor":{"display_login":"chrisdone"}}