Skip to content

Commit 9b12ea9

Browse files
author
Your Name
committed
wip
1 parent 4604cf4 commit 9b12ea9

1 file changed

Lines changed: 97 additions & 0 deletions

File tree

src/Hell.hs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE DeriveAnyClass #-}
12
{-# LANGUAGE AllowAmbiguousTypes #-}
23
{-# LANGUAGE BangPatterns #-}
34
{-# LANGUAGE BlockArguments #-}
@@ -42,8 +43,13 @@
4243

4344
module 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
4651
import qualified Control.Unification as FD
52+
import qualified Control.Unification.STVar as FD
4753
import GHC.Generics (Generic1)
4854
import 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
5562
import qualified Data.CaseInsensitive as CI
5663
import Data.CaseInsensitive (CI, FoldCase)
5764
import 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>
26512724
irep_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

Comments
 (0)