packages feed

th-instances 0.1.0.3 → 0.1.0.14

raw patch · 3 files changed

+262/−23 lines, 3 filesdep +derivedep +mtldep +th-kindsdep ~template-haskell

Dependencies added: derive, mtl, th-kinds, th-lift

Dependency ranges changed: template-haskell

Files

src/Language/Haskell/TH/Instances.hs view
@@ -1,56 +1,92 @@+{-# LANGUAGE TemplateHaskell, QuasiQuotes #-} {- | A grab bag of useful instances for Template Haskell types -}-module Language.Haskell.TH.Instances where+module Language.Haskell.TH.Instances (+    module Language.Haskell.TH.Lift,+    module Language.Haskell.TH.LiftInstances,+    haskell_98_data_dec,+    type_arb, +    kind_arb,+    haskell_98_type_arb,+    primitive_types+) where      import Language.Haskell.TH+import Language.Haskell.TH.Lift+import Language.Haskell.TH.Syntax import Data.String import Test.QuickCheck import Control.Applicative import Test.QuickCheck.Instances.Char+import Control.Monad.Reader+import Data.List+import Language.Haskell.TH.LiftInstances+import Data.Char+import Data.DeriveTH +import qualified Language.Haskell.TH.Lift as L++clamp x y = if x < y+    then x+    else y+ instance IsString Name where     fromString x = mkName x      instance Arbitrary Name where-    arbitrary = mkName <$> arbitrary+    arbitrary = sized $ \x -> do+         c <- lowerAlpha+         mkName <$> (c:) <$> vectorOf (clamp 20 x) (oneof [numeric, lowerAlpha, upperAlpha])          arb_constructor_name = do      x <- upperAlpha-    xs <- listOf (oneof [numeric, lowerAlpha, upperAlpha])+    name_size <- choose (5, 20)+    xs <- sized (\x -> vectorOf name_size (oneof [numeric, lowerAlpha, upperAlpha]))     return $ mkName $ x:xs  instance Arbitrary Type where     arbitrary = sized type_arb-+    shrink (VarT _) = []+    shrink (ConT _) = []+    shrink (TupleT _) = []+    shrink (UnboxedTupleT _) = []+    shrink (ArrowT) = []+    shrink (ListT) = []+    shrink (ForallT x y z) = [ForallT x' y' z' | x' <- shrink x, y' <- shrink y, +                                                 z' <- shrink z]    +    shrink (SigT typ knd)  = [SigT t k | t <- shrink typ, k <- shrink knd]+    shrink (AppT x y)      = [x, y]+    +     type_arb :: Int -> Gen Type        type_arb depth = do-        let max_option = if depth > 0 then 8 else (5 :: Int)+        let new_depth = depth `div` 2+            max_option = if depth > 0 then 8 else 5 :: Int         typ <- choose (0, max_option)         case typ of-            0 -> VarT <$> mkName <$> listOf lowerAlpha+            0 -> VarT <$> mkName <$> vectorOf 20 lowerAlpha             1 -> ConT <$> arb_constructor_name             2 -> TupleT <$> arbitrary             3 -> UnboxedTupleT <$> arbitrary              4 -> return ArrowT             5 -> return ListT-            6 -> forallt_arb (depth - 1)-            7 -> SigT <$> type_arb (depth - 1) <*> arbitrary-            8 -> AppT <$> type_arb (depth - 1) <*> type_arb (depth - 1)+            6 -> ForallT <$> vectorOf (clamp 5 new_depth) (arb_ty_var_bndr (clamp 3 new_depth)) <*> +                             vectorOf (clamp 5 new_depth) (arb_pred        (clamp 3 new_depth)) <*> +                             type_arb new_depth+            7 -> SigT <$> type_arb new_depth <*> kind_arb new_depth+            8 -> AppT <$> type_arb new_depth <*> type_arb new_depth             ---this needs work but I have no use for it now-forallt_arb :: Int -> Gen Type-forallt_arb depth = do-    ForallT <$> (return []) <*> (return []) <*> (return $ VarT $ mkName "test")      instance Arbitrary Kind where     arbitrary = sized kind_arb  kind_arb :: Int -> Gen Kind        +kind_arb 0 = return StarK kind_arb depth = do-    let max_option = if depth > 0 then 1 else (2 :: Int)-    typ <- choose(0, max_option)+    typ <- choose(0, 1 :: Int)     case typ of          0 -> return StarK-        1 -> ArrowK <$> kind_arb (depth - 1) <*> kind_arb (depth - 1)+        1 -> ArrowK <$> kind_arb (depth `div` 2)+                    <*> kind_arb (depth `div` 2)      haskell_98_type_arb depth = do     let max_option = if depth > 0 then 6 else (5 :: Int)@@ -62,17 +98,164 @@         3 -> UnboxedTupleT <$> arbitrary          4 -> return ArrowT         5 -> return ListT-        6 -> AppT <$> haskell_98_type_arb (depth - 1) <*> haskell_98_type_arb (depth - 1)-        +        6 -> AppT <$> haskell_98_type_arb (depth `div` 2) +                  <*> haskell_98_type_arb (depth `div` 2)         +letter_strings =  map (\x -> mkName $ (x:[])) $ take 26 ['a'..] +instance Arbitrary Strict where+    arbitrary = oneof [return IsStrict, return NotStrict]++instance Arbitrary TyVarBndr where+    arbitrary = sized arb_ty_var_bndr where++arb_ty_var_bndr 0 = PlainTV <$> arbitrary+arb_ty_var_bndr size = do+    option <- arbitrary+    if option +        then PlainTV  <$> arbitrary +        else KindedTV <$> arbitrary <*> kind_arb (size `div` 2)         ++instance Arbitrary Pred where+    arbitrary = sized arb_pred where+++arb_pred 0 = return $ ClassP (mkName "test") [ConT $ mkName "test"]+arb_pred size = do+    option <- arbitrary+    if option +        then ClassP <$> arbitrary <*> vectorOf size (type_arb (size `div` 2))+        else EqualP <$> type_arb (size `div` 2) <*>  type_arb (size `div` 2)++instance Arbitrary Con where+    arbitrary = sized arb_con where++arb_con 0 = arb_con' 0 (2 :: Int)+arb_con size = arb_con' size 3+arb_con' size max_option = do+    option <- choose (0, max_option)+    case option of +        0 -> NormalC <$> arbitrary <*> arbitrary+        1 -> RecC <$> arbitrary <*> arbitrary+        2 -> InfixC <$> arbitrary <*> arbitrary <*> arbitrary+        3 -> ForallC <$> arbitrary <*> arbitrary <*> arb_con (size - 1) +--the right way to do this is probably to gen a simply typed environment +--and sample functions from it, and convert+--what I really need to do, is first I generate ++--name of data -> name of ty_var -> kind+--type KindEnv = [(Name, [(Name, Kind)])]++--look_up_kind env = undefined+--extend name kind = undefined++safe_prefix name =  map (replace_symbol . toLower) name++replace_symbol '[' = 'z'+replace_symbol ']' = 'q'+replace_symbol x = x++collect_kinded_tyvars :: Dec -> [TyVarBndr]+collect_kinded_tyvars (DataD _ _ tyvars _ _ ) = tyvars+collect_kinded_tyvars (NewtypeD _ _ tyvars _ _ ) = tyvars+ +prefix_ty_var :: Name -> TyVarBndr -> TyVarBndr+prefix_ty_var name (KindedTV ty_name kind) = KindedTV (mkName $ (safe_prefix $ nameBase name) ++ ("_") ++ (show ty_name)) kind++prefix_ty_vars :: Dec -> Dec+prefix_ty_vars (DataD x name tyvars z w ) = DataD x name (map (prefix_ty_var name) tyvars) z w+prefix_ty_vars (NewtypeD x name tyvars z w ) = NewtypeD x name (map (prefix_ty_var name) tyvars) z w++ty_var_kind :: TyVarBndr -> Kind+ty_var_kind (KindedTV _ kind) = kind++ty_var_name :: TyVarBndr -> Name+ty_var_name (KindedTV name _ ) = name+ty_var_name (PlainTV name) = name++set_ty_var_name :: Name -> TyVarBndr -> TyVarBndr+set_ty_var_name n (KindedTV _ k) = KindedTV n k++group_by_kind :: [TyVarBndr] -> [[TyVarBndr]]+group_by_kind tyvars = groupBy (\x y -> ty_var_kind x == ty_var_kind y ) tyvars++possibly_share :: Bool -> [TyVarBndr] -> [TyVarBndr]+--possibly_share True (x:xs) = result where+--    name   = ty_var_name x+--    new_xs = map (set_ty_var_name name) xs+--   result = x:xs+possibly_share _ x = x++possibly_make_plain :: Bool -> TyVarBndr -> TyVarBndr+possibly_make_plain _ (KindedTV n _) = PlainTV n+--possibly_make_plain _ x = x++dec_to_typ :: Dec -> Type+dec_to_typ (DataD _ name ty_vars _ _) = foldl' AppT (ConT name) $ map (VarT . ty_var_name) ty_vars+dec_to_typ (NewtypeD _ name ty_vars _ _) = foldl' AppT (ConT name) $ map (VarT . ty_var_name) ty_vars++--type KindContext = ReaderT KindEnv Gen++haskell_98_data_dec :: [Dec] -> Gen Dec+haskell_98_data_dec other_types = do+    --all of the dec must be explictly kinded!+    name <- arb_constructor_name+    ty_var_size <- choose (0, 10)+    typ_vars    <- vectorOf ty_var_size (elements letter_strings)+                  +    concre_size <- choose (0, 10)+    concre_typs <- vectorOf concre_size (elements other_types)+    +    let renamed_concre_decs = map prefix_ty_vars concre_typs+        renamed_concre_typs = map dec_to_typ renamed_concre_decs+        all_ty_var_bndrs    = nub $ concatMap collect_kinded_tyvars renamed_concre_decs+        grouped = group_by_kind all_ty_var_bndrs+    +    should_share <- vectorOf (length grouped) arbitrary         +    let shared  = concat $ zipWith possibly_share should_share grouped+    +    should_make_plain <- vectorOf (length shared) arbitrary +    let ty_var_bndrs  = zipWith possibly_make_plain should_make_plain shared+        typ_var_names = map ty_var_name ty_var_bndrs    +        var_types     = map VarT typ_var_names+    cons <- if length renamed_concre_typs > 0 +               then mapM arb_con_with_types =<< small_list_of (small_list_of $ elements (renamed_concre_typs))  -- ++ var_types+               else (:[]) <$> arb_con_with_types []+    index        <- choose(0, length cons - 1)     +    return $ DataD [] name ty_var_bndrs cons []      +arb_field_name = do+        x <- lowerAlpha+        name_size <- choose (10, 30)+        xs <- vectorOf name_size (oneof [numeric, lowerAlpha, upperAlpha])+        return $ mkName $ x:xs++arb_con_with_types :: [Type] -> Gen Con+arb_con_with_types xs = do+    name <- arb_constructor_name+    ss <- vectorOf (length xs) $ oneof [return IsStrict, return NotStrict]+    option <- choose (0, 1 :: Int)+    case option of+        0 -> return $ NormalC name $ zip ss xs+        1 -> do+             field_names <- vectorOf (length xs) arb_field_name+             let var_strict_types = zip3 field_names ss xs+             return $ RecC name var_strict_types+             +++primitive_types = $(L.lift =<< mapM explictly_kind [''Int, ''Bool, ''Char, ''Float, ''[]])     ++small_list_of elems = do+    size <- choose (0, 10)+    vectorOf size elems     +               
+ src/Language/Haskell/TH/LiftInstances.hs view
@@ -0,0 +1,46 @@+{-# LANGUAGE TemplateHaskell, QuasiQuotes #-}+{- | A grab bag of useful instances for Template Haskell types -}+module Language.Haskell.TH.LiftInstances where+    +import qualified Language.Haskell.TH.Lift as L+import Language.Haskell.TH+import Language.Haskell.TH.Syntax+--import Language.Haskell.TH.LambdaConvert+import Language.Haskell.TH.KindInference++$(L.deriveLiftMany [''Match, ''Range, ''Stmt, ''Strict,+                  ''InlineSpec,+                  ''Safety,+                  ''Callconv,+                  ''Guard,+                  ''Lit,+                  ''Exp, ''FixityDirection, ''Clause, ''Pat,+                  ''Body, ''FunDep, ''Foreign,+                  ''Pragma, ''FamFlavour, ''TyVarBndr,+                  ''Kind, ''Pred, ''Con, +                  ''Dec, ''ClassInstance, ''Type, ''Fixity, ''Info])+                  +un_ty_con (TyConI x) = x++explictly_kind name = do+    Right kind      <- inferKind name+    TyConI data_dec <- reify name+    return $ convert_ty_vars data_dec kind+    +    +convert_ty_vars :: Dec -> Kind -> Dec+convert_ty_vars (DataD x y ty_vars z w) kind    = DataD x y (replace_ty_vars ty_vars kind) z w+convert_ty_vars (NewtypeD x y ty_vars z w) kind = NewtypeD x y (replace_ty_vars ty_vars kind) z w+ +replace_ty_vars ty_vars kind = result where+    kinds = unfold_kinds kind (length ty_vars)+    result = zipWith add_kind ty_vars kinds+    +unfold_kinds x y = unfold_kinds' x y []+    +unfold_kinds' _ 0        accum = accum+unfold_kinds' (ArrowK x y) i accum = unfold_kinds' y (i - 1) (x:accum)++add_kind (PlainTV n) k = KindedTV n k+add_kind x k = x+
th-instances.cabal view
@@ -7,7 +7,7 @@ -- The package version. See the Haskell package versioning policy -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for -- standards guiding when and how versions should be incremented.-Version:             0.1.0.3+Version:             0.1.0.14  -- A short (one-line) description of the package. Synopsis: A place to collect orphan instances for Template Haskell@@ -46,13 +46,17 @@ Library   Hs-Source-Dirs: src   -- Modules exported by the library.-  Exposed-modules: Language.Haskell.TH.Instances+  Exposed-modules: Language.Haskell.TH.Instances, Language.Haskell.TH.LiftInstances      -- Packages needed in order to build this package.   Build-depends: base > 4.0.0 && <= 5.0,                  template-haskell >= 2.6.0,                  QuickCheck >= 2.4.1.1,-                 checkers >= 0.2.8+                 checkers >= 0.2.8,+                 th-lift >= 0.5.4,+                 th-kinds >= 0.1.1,+                 mtl >= 2.0.1.0,+                 derive >= 2.5.4   ghc-options:            -Wall     Test-Suite tests@@ -64,5 +68,11 @@                  test-framework-quickcheck2 >= 0.2.10,                  test-framework-hunit >= 0.2.7,                  test-framework >= 0.4.1.1,-                 HUnit >= 1.2.4.2-  +                 HUnit >= 1.2.4.2,+                 QuickCheck >= 2.4.1.1,+                 th-lift >= 0.5.4,+                 th-kinds >= 0.1.1,+                 mtl >= 2.0.1.0,+                 template-haskell >= 2.6.0,+                 checkers >= 0.2.8,+                 derive >= 2.5.4