1+ {-# LANGUAGE DeriveAnyClass #-}
12{-# LANGUAGE AllowAmbiguousTypes #-}
23{-# LANGUAGE BangPatterns #-}
34{-# LANGUAGE BlockArguments #-}
4243
4344module Main (main , specMain ) where
4445
46+
4547#if __GLASGOW_HASKELL__ >= 906
48+ import Data.Fix
49+ import qualified Control.Unification.Types as FD
50+ import Control.Monad.Except
4651import qualified Control.Unification as FD
52+ import qualified Control.Unification.STVar as FD
4753import GHC.Generics (Generic1 )
4854import Control.Monad
4955#endif
@@ -52,6 +58,7 @@ import Control.Monad
5258-- e.g. 'Data.Graph' becomes 'Graph', and are then exposed to the Hell
5359-- guest language as such.
5460
61+ import Control.Monad.ST
5562import qualified Data.CaseInsensitive as CI
5663import Data.CaseInsensitive (CI , FoldCase )
5764import qualified Network.HTTP.Types as Http
@@ -2646,6 +2653,72 @@ data Ty a
26462653 | TyFun a a
26472654 | TyCon SomeTypeRep
26482655 deriving (Functor , Traversable , Foldable , Eq , Ord , Show , Generic1 )
2656+ -- Below: Needed for FD.freeVar (note for myself, not audience)
2657+ deriving instance FD. Unifiable Ty
2658+
2659+ -- WIP: At this point we want, preferably, a function that goes
2660+ -- from an (IRep IMetaVar) to SomeTypeRep in one go, which inferExp can
2661+ -- use to traverse f iterm to get UTerm SomeTypeRep.
2662+ --
2663+ -- Some key ingredients:
2664+ --
2665+ -- to_sometyperep :: Fix Ty -> Either ZonkError SomeTypeRep
2666+ -- irep_to_uterm :: IRep v -> FD.UTerm Ty v
2667+ -- FD.applyBindings :: UTerm t v -> em m (UTerm t v)
2668+ --
2669+ -- I'd say we want to:
2670+ --
2671+ -- 1) Convert the IRep IMetaVar to UTerm t v using the (Map IMetaVar (STVar ..)) map.
2672+ -- 2) Apply bindings to fully flesh out the type.
2673+ -- 3) Zonk it, going directly from FD.UTerm Ty straight to SomeTypeRep
2674+ -- (tweak to_sometyperep to work with UTerm Ty rather than Fix Ty)
2675+ --
2676+ -- That should be all that's needed?
2677+
2678+ -- Not useful; leaving for reading purposes.
2679+ st_unstize_var :: FD. STVar s Ty
2680+ -> FD. STBinding s (Maybe (IRep (FD. STVar s Ty )))
2681+ st_unstize_var stv = do
2682+ m <- FD. lookupVar stv
2683+ case m of
2684+ Nothing -> pure Nothing
2685+ Just v -> pure $ Just $ uterm_to_irep v
2686+
2687+ -- Unify all the equality constraints provided.
2688+ st_unifier :: [Equality (FD. UTerm Ty (FD. STVar s Ty ))]
2689+ -> ExceptT (FD. UFailure Ty (FD. STVar s Ty ))
2690+ (FD. STBinding s )
2691+ ()
2692+ st_unifier = traverse_ \ (Equality src a b) -> void $ FD. unify a b
2693+
2694+ -- Run an ST-izing operation, and return the mapping from the original IMetaVars to the STVars, so that they can be recovered later.
2695+ run_stize :: StateT (Map IMetaVar (FD. STVar s Ty )) (FD. STBinding s ) x -> FD. STBinding s (x , Map IMetaVar (FD. STVar s Ty ))
2696+ run_stize = flip runStateT (mempty :: Map IMetaVar (FD. STVar s Ty ))
2697+
2698+ -- ST-ize the metavars in all types in the equality constraints set
2699+ stize_equalities :: [Equality (IRep IMetaVar )] -> StateT (Map IMetaVar (FD. STVar s Ty )) (FD. STBinding s ) [Equality (FD. UTerm Ty (FD. STVar s Ty ))]
2700+ stize_equalities = traverse stize_equality
2701+
2702+ -- ST-ize the metavars in all types in the equality's types on both sides, it also
2703+ -- is exactly where conversion from IRep to UTerm Ty occurs.
2704+ stize_equality :: Equality (IRep IMetaVar ) -> StateT (Map IMetaVar (FD. STVar s Ty )) (FD. STBinding s ) (Equality (FD. UTerm Ty (FD. STVar s Ty )))
2705+ stize_equality (Equality loc a b) = do
2706+ Equality loc <$> stize_uterm (irep_to_uterm a) <*> stize_uterm (irep_to_uterm b)
2707+
2708+ -- ST-ize the metavars in a uterm
2709+ stize_uterm :: FD. UTerm Ty IMetaVar -> StateT (Map IMetaVar (FD. STVar s Ty )) (FD. STBinding s ) (FD. UTerm Ty (FD. STVar s Ty ))
2710+ stize_uterm = traverse stize_imetavar
2711+
2712+ -- ST-ize this metavar and remember that it was done
2713+ stize_imetavar :: IMetaVar -> StateT (Map IMetaVar (FD. STVar s Ty )) (FD. STBinding s ) (FD. STVar s Ty )
2714+ stize_imetavar = \ v -> do
2715+ mexisting <- gets (Map. lookup v)
2716+ case mexisting of
2717+ Just stv -> pure stv
2718+ Nothing -> do
2719+ stv <- lift FD. freeVar
2720+ modify' (Map. insert v stv)
2721+ pure stv
26492722
26502723-- <bijection>
26512724irep_to_uterm :: IRep v -> FD. UTerm Ty v
@@ -2662,6 +2735,30 @@ uterm_to_irep = \case
26622735 FD. UTerm (TyCon t) -> ICon t
26632736-- </bijection>
26642737
2738+ -- | (unification-fd edition)
2739+ -- A complete implementation of conversion from the inferer's type
2740+ -- rep to some star type, ready for the type checker.
2741+ to_sometyperep :: Fix Ty -> Either ZonkError SomeTypeRep
2742+ to_sometyperep t = do
2743+ go t
2744+ where
2745+ go :: Fix Ty -> Either ZonkError SomeTypeRep
2746+ go = \ case
2747+ Fix (TyCon someTypeRep) -> pure someTypeRep
2748+ Fix (TyFun a b) -> do
2749+ a' <- go a
2750+ b' <- go b
2751+ case (a', b') of
2752+ (StarTypeRep aRep, StarTypeRep bRep) ->
2753+ pure $ StarTypeRep (Type. Fun aRep bRep)
2754+ _ -> Left ZonkKindError
2755+ Fix (TyApp f a) -> do
2756+ f' <- go f
2757+ a' <- go a
2758+ case applyTypes f' a' of
2759+ Just someTypeRep -> pure someTypeRep
2760+ _ -> Left ZonkKindError
2761+
26652762--------------------------------------------------------------------------------
26662763-- Inference type representation
26672764
0 commit comments