HList-0.5.2.0: examples/Properties/KW.hs
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE NoMonoLocalBinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE CPP #-}
module Properties.KW where
import Properties.Common
import Test.QuickCheck
import Data.HList.CommonMain
import Test.Hspec
kwSpecs = describe "kw" $ do
{- with NoMonoLocalBinds
- /home/aavogt/wip/HList/HList/examples/Properties/KW.hs:59:15: error:ghc: panic! (the 'impossible' happened)
(GHC version 8.0.2 for x86_64-unknown-linux):
No skolem info: k_aqoh[sk]
with MonoLocalBinds, I think the error is the same as in earlier versions
/home/aavogt/wip/HList/HList/examples/Properties/KW.hs:62:15: error:
• Couldn't match type ‘'[Tagged "x" (BoolN "x")]’ with ‘'[]’
Expected type: Record '[]
Actual type: HExtendR (Tagged "x" (BoolN "x")) (Record '[])
• In the first argument of ‘f2’, namely
‘(lx .=. x2 .*. emptyRecord)’
In the first argument of ‘eq’, namely
‘f2 (lx .=. x2 .*. emptyRecord)’
In the expression: f2 (lx .=. x2 .*. emptyRecord) `eq` f1 x2 y
/home/aavogt/wip/HList/HList/examples/Properties/KW.hs:63:15: error:
• Couldn't match type ‘'[Tagged "y" (BoolN "y")]’ with ‘'[]’
Expected type: Record '[]
Actual type: HExtendR (Tagged "y" (BoolN "y")) (Record '[])
• In the first argument of ‘f2’, namely
‘(ly .=. y2 .*. emptyRecord)’
In the first argument of ‘eq’, namely
‘f2 (ly .=. y2 .*. emptyRecord)’
In the expression: f2 (ly .=. y2 .*. emptyRecord) `eq` f1 x y2
/home/aavogt/wip/HList/HList/examples/Properties/KW.hs:64:15: error:
• Couldn't match type ‘'[Tagged "x" (BoolN "x"),
Tagged "y" (BoolN "y")]’
with ‘'[]’
Expected type: Record '[]
Actual type: HExtendR
(Tagged "x" (BoolN "x")) (Record '[Tagged "y" (BoolN "y")])
• In the first argument of ‘f2’, namely
‘(lx .=. x2 .*. ly .=. y2 .*. emptyRecord)’
In the first argument of ‘eq’, namely
‘f2 (lx .=. x2 .*. ly .=. y2 .*. emptyRecord)’
In the expression:
f2 (lx .=. x2 .*. ly .=. y2 .*. emptyRecord) `eq` f1 x2 y2
/home/aavogt/wip/HList/HList/examples/Properties/KW.hs:65:15: error:
• Couldn't match type ‘'[Tagged "y" (BoolN "y"),
Tagged "x" (BoolN "x")]’
with ‘'[]’
Expected type: Record '[]
Actual type: HExtendR
(Tagged "y" (BoolN "y")) (Record '[Tagged "x" (BoolN "x")])
• In the first argument of ‘f2’, namely
‘(ly .=. y2 .*. lx .=. x2 .*. emptyRecord)’
In the first argument of ‘eq’, namely
‘f2 (ly .=. y2 .*. lx .=. x2 .*. emptyRecord)’
In the expression:
f2 (ly .=. y2 .*. lx .=. x2 .*. emptyRecord) `eq` f1 x2 y2
-}
it "f1" $ property $ do
(f1 :: BoolN "x" -> BoolN "y") <- arbitrary
x :: BoolN "x" <- arbitrary
x2 :: BoolN "x" <- arbitrary
let f2 (Label :: Label "x") x () = f1 x
f = f2 .*. recToKW [pun| x |]
return $ conjoin
[ kw f lx x2 () `eq` f1 x2,
kw f () `eq` f1 x ]
-- a function of two arguments can be made into a keyword function
it "f2" $ property $ do
(f1 :: BoolN "x" -> BoolN "y" -> BoolN "z") <- arbitrary
x :: BoolN "x" <- arbitrary
x2 :: BoolN "x" <- arbitrary
y :: BoolN "y" <- arbitrary
y2 :: BoolN "y" <- arbitrary
let f2 (_ :: Label "x") x (_ :: Label "y") y () = f1 x y
f = f2 .*. recToKW [pun| x y |]
return $ conjoin
[ kw f lx x2 ly y2 () `eq` f1 x2 y2,
kw f ly y2 lx x2 () `eq` f1 x2 y2,
kw f ly y2 () `eq` f1 x y2,
kw f lx x2 () `eq` f1 x2 y,
kw f () `eq` f1 x y ]
-- alternatively, a function taking a record is pretty much
-- a keyword argument. Error messages for missing keywords
-- are a bit worse (blame hRearrange')
it "f2Alt" $ property $ do
(f1 :: BoolN "x" -> BoolN "y" -> BoolN "z") <- arbitrary
x :: BoolN "x" <- arbitrary
x2 :: BoolN "x" <- arbitrary
y :: BoolN "y" <- arbitrary
y2 :: BoolN "y" <- arbitrary
let addDef new = hRearrange (Proxy :: Proxy [Label "x", Label "y"]) (new .<++. [pun| x y |])
f2 (addDef -> [pun| (x y) |]) = f1 x y
return $ conjoin
[ f2 emptyRecord `eq` f1 x y,
f2 (lx .=. x2 .*. emptyRecord) `eq` f1 x2 y,
f2 (ly .=. y2 .*. emptyRecord) `eq` f1 x y2,
f2 (lx .=. x2 .*. ly .=. y2 .*. emptyRecord) `eq` f1 x2 y2,
f2 (ly .=. y2 .*. lx .=. x2 .*. emptyRecord) `eq` f1 x2 y2
]