reflection 1.5.1.1 → 1.5.1.2
raw patch · 4 files changed
+79/−5 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG.markdown +4/−0
- examples/FromJSON.hs +70/−0
- fast/Data/Reflection.hs +3/−4
- reflection.cabal +2/−1
CHANGELOG.markdown view
@@ -1,3 +1,7 @@+# 1.5.1.2+* Builds warning-free on GHC 7.10.+* Added a dynamic FromJSON example.+ # 1.5.1.1 * Updated the link to the paper. * More examples.
+ examples/FromJSON.hs view
@@ -0,0 +1,70 @@+-- Example of a dynamically generated FromJSON instance.+--+-- Can be useful when one needs to use a function with a +-- FromJSON constraint, but some detail about the +-- conversion from JSON is not known until runtime.+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE OverloadedStrings #-}++import Data.Reflection -- from reflection+import Data.Monoid -- from base+import Data.Proxy -- from tagged+import Data.Text -- from text+import Data.Monoid +import Data.Aeson -- from aeson +import Data.Aeson.Types (Parser)++import Control.Applicative++-- These imports are only for constructing the example value+import Control.Lens (preview) -- from lens+import Data.Aeson.Lens (_Value,_String) -- form lens-aeson++data Foo = Foo+ {+ field1 :: Int+ , field2 :: Int+ } deriving (Show)++fooParser :: Text -> Object -> Parser Foo+fooParser prefix o = do+ Foo <$> o .: (prefix <> "field1") <*> o .: (prefix <> "field2")++-- A wrapper over Foo carrying a phantom type s+newtype J a s = J { runJ :: a }+ +-- If the phantom type s reifies the parsing function, we can +-- use reflect to recover the function and implement +-- our FromJSON instance for J.+instance Reifies s (Object -> Parser a) => FromJSON (J a s) where+ parseJSON (Object v) = J <$> reflect (Proxy :: Proxy s) v+ +-- Convince the compiler that the phantom type in the proxy+-- supplied by reify is the same as the phantom type in J. +--+-- Otherwise the FromJSON instance for J won't kick in.+asProxyJ :: Proxy s -> J a s -> J a s+asProxyJ _ = id++exampleJSON :: Value+exampleJSON = maybe Null id (preview _Value str)+ where+ str = "{ \"zzfield1\" : 5, \"zzfield2\" : 7 }"::Text+ +main :: IO ()+main = do+ putStrLn "Enter prefix for the fields: "+ -- "zz" must be entered for the parse to succeed+ prefix <- fmap pack getLine+ + -- fromJSON uses the dynamically generated FromJSON instance+ let result = reify (fooParser prefix) $ \proxy ->+ -- We must eliminate the J newtype before returning+ -- because, thanks to parametricity,+ -- the phantom type cannot escape the callback.+ runJ . asProxyJ proxy <$> fromJSON exampleJSON + + putStrLn (show (result :: Result Foo))
fast/Data/Reflection.hs view
@@ -69,7 +69,6 @@ , Z, D, SD, PD ) where -import Data.Functor import Data.Proxy #if (defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707) || (TEMPLATE_HASKELL && USE_TYPE_LITS)@@ -155,15 +154,15 @@ {-# INLINE retagPD #-} instance Reifies n Int => Reifies (D n) Int where- reflect = (\n -> n + n) <$> retagD reflect+ reflect = (\n -> n + n) `fmap` retagD reflect {-# INLINE reflect #-} instance Reifies n Int => Reifies (SD n) Int where- reflect = (\n -> n + n + 1) <$> retagSD reflect+ reflect = (\n -> n + n + 1) `fmap` retagSD reflect {-# INLINE reflect #-} instance Reifies n Int => Reifies (PD n) Int where- reflect = (\n -> n + n - 1) <$> retagPD reflect+ reflect = (\n -> n + n - 1) `fmap` retagPD reflect {-# INLINE reflect #-} #ifdef TEMPLATE_HASKELL
reflection.cabal view
@@ -1,5 +1,5 @@ name: reflection-version: 1.5.1.1+version: 1.5.1.2 license: BSD3 license-file: LICENSE author: Edward A. Kmett, Elliott Hird, Oleg Kiselyov and Chung-chieh Shan@@ -71,6 +71,7 @@ extra-source-files: examples/Monoid.hs+ examples/FromJSON.hs examples/Constraints.hs examples/Benchmark.hs CHANGELOG.markdown