on master help sign in
Optimise positional lens and use ghc-proofs for testing
commit3fddfc5b9fde0904e452a1866515fd493b914c67 authorCsongor Kiss <kiss.csongor.kiss@gmail.com> dateWed 6 Sep 2017, 13:16 (9 years ago) parent5da262d
4 files changed+66−7
generic-lens.cabal+5−2 src/Data/Generics/Product/Positions.hs+1−1 stack.yaml+3−3 test/Spec.hs+57−1
generic-lens.cabal+5−2
@@ -41,6 +41,10 @@ library
4141 , Data.Generics.Sum.Internal.Typed
4242 , Data.Generics.Sum.Internal.Subtype
4343
44+ , Data.Generics.Internal.Families
45+ , Data.Generics.Internal.Families.Count
46+ , Data.Generics.Internal.Families.Has
47+ , Data.Generics.Internal.HList
4448 , Data.Generics.Product.Internal.Fields
4549 , Data.Generics.Product.Internal.Positions
4650 , Data.Generics.Product.Internal.Subtype
@@ -63,9 +67,8 @@ test-suite generic-lens-test
6367 main-is: Spec.hs
6468
6569 build-depends: base >= 4.9 && <= 5.0
66− , QuickCheck
67− , hspec
6870 , generic-lens
71+ , ghc-proofs >= 0.1.1
6972
7073 default-language: Haskell2010
7174 ghc-options: -Wall
src/Data/Generics/Product/Positions.hs+1−1
@@ -93,7 +93,7 @@ instance
9393 , GHasPosition 1 i (Rep s) a
9494 ) => HasPosition i a s where
9595
96− position = repIso . gposition @1 @i
96+ position = ravel (repIso . gposition @1 @i)
9797
9898type family ErrorUnless (i :: Nat) (s :: Type) (hasP :: Bool) :: Constraint where
9999 ErrorUnless i s 'False
stack.yaml+3−3
@@ -1,10 +1,10 @@
1−
2−resolver: lts-8.17
1+resolver: nightly-2017-09-06
32
43packages:
54- '.'
65
7−extra-deps: []
6+extra-deps:
7+- 'ghc-proofs-0.1.1'
88
99flags: {}
1010
test/Spec.hs+57−1
@@ -1 +1,57 @@
1−{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
1+{-# OPTIONS_GHC -O -fplugin GHC.Proof.Plugin #-}
2+
3+{-# LANGUAGE AllowAmbiguousTypes #-}
4+{-# LANGUAGE DataKinds #-}
5+{-# LANGUAGE DeriveGeneric #-}
6+{-# LANGUAGE DuplicateRecordFields #-}
7+{-# LANGUAGE ExistentialQuantification #-}
8+{-# LANGUAGE RankNTypes #-}
9+{-# LANGUAGE ScopedTypeVariables #-}
10+{-# LANGUAGE TypeApplications #-}
11+
12+module Main where
13+
14+import GHC.Generics
15+import Data.Generics.Product
16+import GHC.Proof
17+
18+main :: IO ()
19+main = putStrLn "Hello world"
20+
21+data Record = MkRecord
22+ { fieldA :: Int
23+ , fieldB :: Bool
24+ } deriving Generic
25+
26+data Record2 = MkRecord2
27+ { fieldA :: Int
28+ } deriving Generic
29+
30+type Lens' s a = forall f. Functor f => (a -> f a) -> s -> f s
31+
32+fieldALensManual :: Lens' Record Int
33+fieldALensManual f (MkRecord a b) = (\a' -> MkRecord a' b) <$> f a
34+
35+newtype L s a = L (Lens' s a)
36+
37+subtypeLensManual :: Lens' Record Record2
38+subtypeLensManual f record
39+ = fmap (\ds -> case record of
40+ MkRecord _ b -> MkRecord (case ds of {MkRecord2 g1 -> g1}) b
41+ ) (f (MkRecord2 (case record of {MkRecord a _ -> a})))
42+
43+--------------------------------------------------------------------------------
44+-- * Tests
45+-- The ghc-proofs plugin checks that the following equalities hold, by checking
46+-- that the LHSs and the RHSs are CSEd. This also means that the runtime
47+-- characteristics of the derived lenses is the same as the manually written
48+-- ones above.
49+
50+fieldP :: Proof
51+fieldP = L fieldALensManual === L (field @"fieldA")
52+
53+posP :: Proof
54+posP = L fieldALensManual === L (position @1)
55+
56+subtypeP :: Proof
57+subtypeP = L subtypeLensManual === L super