Created
August 4, 2016 07:06
-
-
Save ekmett/ff3088d1e401b967d6b653a600359ea4 to your computer and use it in GitHub Desktop.
horrible TypeApplications hack for Chris Done
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE GADTs #-} | |
{-# LANGUAGE PolyKinds #-} | |
{-# LANGUAGE FunctionalDependencies #-} | |
{-# LANGUAGE MultiParamTypeClasses #-} | |
{-# LANGUAGE TypeOperators #-} | |
{-# LANGUAGE ScopedTypeVariables #-} | |
{-# LANGUAGE DataKinds #-} | |
{-# LANGUAGE KindSignatures #-} | |
{-# LANGUAGE TemplateHaskell #-} | |
{-# LANGUAGE FlexibleInstances #-} | |
{-# LANGUAGE TypeApplications #-} | |
{-# LANGUAGE AllowAmbiguousTypes #-} | |
-- | This module provides a way to name the fields in a regular | |
-- Haskell tuple and then look them up later, statically. | |
module NamedTuple where | |
import Data.String | |
import Language.Haskell.TH | |
import Data.Proxy | |
import GHC.TypeLits | |
-- | The syntax and the type of a field assignment. | |
data l := t where | |
Set :: KnownSymbol l => t -> l := t | |
symbolVal_ :: forall n. KnownSymbol n => String | |
symbolVal_ = symbolVal (Proxy @n) | |
-- Simple show instance for a field. | |
instance Show t => Show (l := t) where | |
show (Set t) = symbolVal_ @l ++ " := " ++ show t | |
-- | Means to search for a field within a tuple. | |
-- We could add `set` to this, or just have a `lens` method | |
-- which generates a lens for that field. | |
class Has (l :: Symbol) r a | l r -> a where | |
get :: r -> a | |
-- Instances which we could easily generate with TH. | |
instance Has l (l := a, u0) a where get (Set a,_) = a | |
instance Has l (u0, l := a) a where get (_,Set a) = a | |
instance Has l (l := a, u0, u1) a where get (Set a,_,_) = a | |
instance Has l (u0, l := a, u1) a where get (_,Set a,_) = a | |
instance Has l (u0, u1, l := a) a where get (_,_,Set a) = a | |
mentioned = | |
( | |
Set @"url" "https://api.github.com/repos/commercialhaskell/intero/issues/64", | |
Set @"title" "Support GHCJS", | |
Set @"user" ( | |
Set @"login" "themoritz", | |
Set @"id" 3522732 | |
) | |
) | |
-- get @"url" mentioned -- now works, you can keep the old := constructor at the value level if you prefer and make 'Set' a combinator. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment