{-# LANGUAGE NumDecimals #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module AutoTupleSpec where import Control.Monad (replicateM) import Control.Monad.State (evalState) import Data.Either (isRight) import Development.IDE.GHC.Compat.Core ( mkVarOcc, mkBoxedTupleTy ) import System.IO.Unsafe import Test.Hspec import Test.QuickCheck import Wingman.Judgements (mkFirstJudgement) import Wingman.Machinery import Wingman.Tactics (auto') import Wingman.Types spec :: Spec spec = describe "auto for tuple" $ do it "should always be able to discover an auto solution" $ do property $ do -- Pick some number of variables n <- choose (1, 7) let vars = flip evalState defaultTacticState $ replicateM n newUnivar -- Pick a random ordering in_vars <- shuffle vars -- Randomly associate them into tuple types in_type <- mkBoxedTupleTy . fmap mkBoxedTupleTy <$> randomGroups in_vars out_type <- mkBoxedTupleTy . fmap mkBoxedTupleTy <$> randomGroups vars pure $ -- We should always be able to find a solution unsafePerformIO (runTactic 2e6 emptyContext (mkFirstJudgement emptyContext (Hypothesis $ pure $ HyInfo (mkVarOcc "x") UserPrv $ CType in_type) True out_type) (auto' $ n * 2)) `shouldSatisfy` isRight randomGroups :: [a] -> Gen [[a]] randomGroups [] = pure [] randomGroups as = do n <- choose (1, length as) (:) <$> pure (take n as) <*> randomGroups (drop n as)