\begin{code}
{-# OPTIONS -cpp #-}
module MagicHaskeller.DebMT where
import MagicHaskeller.Types as Types
import MagicHaskeller.TyConLib
import Control.Monad
import Control.Monad.Search.Combinatorial
import MagicHaskeller.PriorSubsts
import Data.Array
import MagicHaskeller.T10((!?))
import Data.List(genericIndex)
import System.IO.Unsafe(unsafeInterleaveIO)
type Possibility e = (Bag e, Subst, TyVar)
data MapType a
= MT {
MapType a -> [a]
tvMT :: [a],
MapType a -> [a]
tcMT :: [a],
MapType a -> [a]
genMT :: [a],
MapType a -> MapType (MapType a)
taMT :: MapType (MapType a),
MapType a -> MapType (MapType a)
funMT :: MapType (MapType a)
}
lookupMT :: MapType a -> Type -> a
lookupMT :: MapType a -> Type -> a
lookupMT MapType a
mt (TV TyVar
tv) = MapType a -> [a]
forall a. MapType a -> [a]
tvMT MapType a
mt [a] -> TyVar -> a
forall i a. Integral i => [a] -> i -> a
`genericIndex` TyVar
tv
lookupMT MapType a
mt (TC TyVar
tc) | TyVar
tc TyVar -> TyVar -> Bool
forall a. Ord a => a -> a -> Bool
< TyVar
0 = MapType a -> [a]
forall a. MapType a -> [a]
genMT MapType a
mt [a] -> TyVar -> a
forall i a. Integral i => [a] -> i -> a
`genericIndex` (-TyVar
1TyVar -> TyVar -> TyVar
forall a. Num a => a -> a -> a
-TyVar
tc)
| Bool
otherwise = MapType a -> [a]
forall a. MapType a -> [a]
tcMT MapType a
mt [a] -> TyVar -> a
forall i a. Integral i => [a] -> i -> a
`genericIndex` TyVar
tc
lookupMT MapType a
mt (TA Type
t0 Type
t1) = MapType a -> Type -> a
forall a. MapType a -> Type -> a
lookupMT (MapType (MapType a) -> Type -> MapType a
forall a. MapType a -> Type -> a
lookupMT (MapType a -> MapType (MapType a)
forall a. MapType a -> MapType (MapType a)
taMT MapType a
mt) Type
t0) Type
t1
lookupMT MapType a
mt (Type
t0:->Type
t1) = MapType a -> Type -> a
forall a. MapType a -> Type -> a
lookupMT (MapType (MapType a) -> Type -> MapType a
forall a. MapType a -> Type -> a
lookupMT (MapType a -> MapType (MapType a)
forall a. MapType a -> MapType (MapType a)
funMT MapType a
mt) Type
t0) Type
t1
retrieve :: Decoder -> Subst -> Subst
retrieve :: Decoder -> Subst -> Subst
retrieve Decoder
deco Subst
sub = [ (Decoder -> TyVar -> TyVar
decodeVar Decoder
deco TyVar
i, Decoder -> Type -> Type
decode Decoder
deco Type
ty) | (TyVar
i, Type
ty) <- Subst
sub ]
decode :: Decoder -> Type -> Type
decode :: Decoder -> Type -> Type
decode Decoder
deco Type
t = (TyVar -> TyVar) -> Type -> Type
mapTV (Decoder -> TyVar -> TyVar
decodeVar Decoder
deco) Type
t
decodeVar :: Decoder -> TyVar -> TyVar
decodeVar (Dec [TyVar]
tvs TyVar
margin) TyVar
tv = case [TyVar]
tvs [TyVar] -> TyVar -> Maybe TyVar
forall t a. (Eq t, Num t) => [a] -> t -> Maybe a
!? TyVar
tv of Maybe TyVar
Nothing -> TyVar
tvTyVar -> TyVar -> TyVar
forall a. Num a => a -> a -> a
+TyVar
margin
Just TyVar
ntv -> TyVar
ntv
encode :: Type -> TyVar -> (Type, Decoder)
encode :: Type -> TyVar -> (Type, Decoder)
encode = Type -> TyVar -> (Type, Decoder)
Types.normalizeVarIDs
mkMT :: TyConLib -> (Type->a) -> MapType a
mkMT :: TyConLib -> (Type -> a) -> MapType a
mkMT TyConLib
tcl Type -> a
f = TyConLib -> Kind -> (Type -> a) -> MapType a
forall a. TyConLib -> Kind -> (Type -> a) -> MapType a
mkMT' TyConLib
tcl Kind
0 Type -> a
f
mkMT' :: TyConLib -> Kind -> (Type->a) -> MapType a
mkMT' :: TyConLib -> Kind -> (Type -> a) -> MapType a
mkMT' TyConLib
tcl Kind
k Type -> a
f = [a]
-> [a]
-> [a]
-> MapType (MapType a)
-> MapType (MapType a)
-> MapType a
forall a.
[a]
-> [a]
-> [a]
-> MapType (MapType a)
-> MapType (MapType a)
-> MapType a
MT [a]
tvTree [a]
tcTree [a]
genTree MapType (MapType a)
taTree MapType (MapType a)
funTree where
tcs :: [(TypeName, TyVar)]
tcs = TyConLib -> Array Kind [(TypeName, TyVar)]
forall a b. (a, b) -> b
snd TyConLib
tcl Array Kind [(TypeName, TyVar)] -> Kind -> [(TypeName, TyVar)]
forall i e. Ix i => Array i e -> i -> e
! Kind
k
tvTree :: [a]
tvTree = [ Type -> a
f (TyVar -> Type
TV TyVar
i) | TyVar
i <- [TyVar
0..] ]
tcTree :: [a]
tcTree = [ Type -> a
f (TyVar -> Type
TC TyVar
i) | TyVar
i <- [TyVar
0..] ]
genTree :: [a]
genTree = [ Type -> a
f (TyVar -> Type
TC TyVar
i) | TyVar
i <- [-TyVar
1,-TyVar
2..] ]
taTree :: MapType (MapType a)
taTree = TyConLib -> Kind -> (Type -> MapType a) -> MapType (MapType a)
forall a. TyConLib -> Kind -> (Type -> a) -> MapType a
mkMT' TyConLib
tcl (Kind
kKind -> Kind -> Kind
forall a. Num a => a -> a -> a
+Kind
1) (\Type
t0 -> TyConLib -> (Type -> a) -> MapType a
forall a. TyConLib -> (Type -> a) -> MapType a
mkMT TyConLib
tcl (\Type
t1 -> Type -> a
f (Type -> Type -> Type
TA Type
t0 Type
t1)))
funTree :: MapType (MapType a)
funTree = if Kind
kKind -> Kind -> Bool
forall a. Eq a => a -> a -> Bool
==Kind
0 then TyConLib -> (Type -> MapType a) -> MapType (MapType a)
forall a. TyConLib -> (Type -> a) -> MapType a
mkMT TyConLib
tcl (\Type
t0 -> TyConLib -> (Type -> a) -> MapType a
forall a. TyConLib -> (Type -> a) -> MapType a
mkMT TyConLib
tcl (\Type
t1 -> Type -> a
f (Type
t0 Type -> Type -> Type
:-> Type
t1))) else TypeName -> MapType (MapType a)
forall a. HasCallStack => TypeName -> a
error TypeName
"mkMT': the kind of functions must always be *"
mkMTIO :: TyConLib -> (Type -> IO a) -> IO (MapType a)
mkMTIO :: TyConLib -> (Type -> IO a) -> IO (MapType a)
mkMTIO TyConLib
tcl Type -> IO a
f = TyConLib -> Kind -> (Type -> IO a) -> IO (MapType a)
forall a. TyConLib -> Kind -> (Type -> IO a) -> IO (MapType a)
mkMTIO' TyConLib
tcl Kind
0 Type -> IO a
f
mkMTIO' :: TyConLib -> Kind -> (Type -> IO a) -> IO (MapType a)
mkMTIO' :: TyConLib -> Kind -> (Type -> IO a) -> IO (MapType a)
mkMTIO' TyConLib
tcl Kind
k Type -> IO a
f = IO (MapType a) -> IO (MapType a)
forall a. IO a -> IO a
unsafeInterleaveIO (IO (MapType a) -> IO (MapType a))
-> IO (MapType a) -> IO (MapType a)
forall a b. (a -> b) -> a -> b
$ ([a]
-> [a]
-> [a]
-> MapType (MapType a)
-> MapType (MapType a)
-> MapType a)
-> IO [a]
-> IO [a]
-> IO [a]
-> IO (MapType (MapType a))
-> IO (MapType (MapType a))
-> IO (MapType a)
forall (m :: * -> *) a1 a2 a3 a4 a5 r.
Monad m =>
(a1 -> a2 -> a3 -> a4 -> a5 -> r)
-> m a1 -> m a2 -> m a3 -> m a4 -> m a5 -> m r
liftM5 [a]
-> [a]
-> [a]
-> MapType (MapType a)
-> MapType (MapType a)
-> MapType a
forall a.
[a]
-> [a]
-> [a]
-> MapType (MapType a)
-> MapType (MapType a)
-> MapType a
MT IO [a]
tvTree IO [a]
tcTree IO [a]
genTree IO (MapType (MapType a))
taTree IO (MapType (MapType a))
funTree where
tcs :: [(TypeName, TyVar)]
tcs = TyConLib -> Array Kind [(TypeName, TyVar)]
forall a b. (a, b) -> b
snd TyConLib
tcl Array Kind [(TypeName, TyVar)] -> Kind -> [(TypeName, TyVar)]
forall i e. Ix i => Array i e -> i -> e
! Kind
k
lazyf :: Type -> IO a
lazyf = IO a -> IO a
forall a. IO a -> IO a
unsafeInterleaveIO (IO a -> IO a) -> (Type -> IO a) -> Type -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> IO a
f
tvTree :: IO [a]
tvTree = [IO a] -> IO [a]
forall a. [IO a] -> IO [a]
interleaveActions ([IO a] -> IO [a]) -> [IO a] -> IO [a]
forall a b. (a -> b) -> a -> b
$ (TyVar -> IO a) -> [TyVar] -> [IO a]
forall a b. (a -> b) -> [a] -> [b]
map (Type -> IO a
f (Type -> IO a) -> (TyVar -> Type) -> TyVar -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyVar -> Type
TV) [TyVar
0..]
tcTree :: IO [a]
tcTree = [IO a] -> IO [a]
forall a. [IO a] -> IO [a]
interleaveActions ([IO a] -> IO [a]) -> [IO a] -> IO [a]
forall a b. (a -> b) -> a -> b
$ (TyVar -> IO a) -> [TyVar] -> [IO a]
forall a b. (a -> b) -> [a] -> [b]
map (Type -> IO a
f (Type -> IO a) -> (TyVar -> Type) -> TyVar -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyVar -> Type
TC) [TyVar
0..]
genTree :: IO [a]
genTree = [IO a] -> IO [a]
forall a. [IO a] -> IO [a]
interleaveActions ([IO a] -> IO [a]) -> [IO a] -> IO [a]
forall a b. (a -> b) -> a -> b
$ (TyVar -> IO a) -> [TyVar] -> [IO a]
forall a b. (a -> b) -> [a] -> [b]
map (Type -> IO a
f (Type -> IO a) -> (TyVar -> Type) -> TyVar -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyVar -> Type
TC) [-TyVar
1,-TyVar
2..]
taTree :: IO (MapType (MapType a))
taTree = TyConLib
-> Kind -> (Type -> IO (MapType a)) -> IO (MapType (MapType a))
forall a. TyConLib -> Kind -> (Type -> IO a) -> IO (MapType a)
mkMTIO' TyConLib
tcl (Kind
kKind -> Kind -> Kind
forall a. Num a => a -> a -> a
+Kind
1) (\Type
t0 -> TyConLib -> (Type -> IO a) -> IO (MapType a)
forall a. TyConLib -> (Type -> IO a) -> IO (MapType a)
mkMTIO TyConLib
tcl (\Type
t1 -> Type -> IO a
lazyf (Type -> Type -> Type
TA Type
t0 Type
t1)))
funTree :: IO (MapType (MapType a))
funTree = TyConLib -> (Type -> IO (MapType a)) -> IO (MapType (MapType a))
forall a. TyConLib -> (Type -> IO a) -> IO (MapType a)
mkMTIO TyConLib
tcl ((Type -> IO (MapType a)) -> IO (MapType (MapType a)))
-> (Type -> IO (MapType a)) -> IO (MapType (MapType a))
forall a b. (a -> b) -> a -> b
$ if Kind
kKind -> Kind -> Bool
forall a. Eq a => a -> a -> Bool
==Kind
0 then (\Type
t0 -> TyConLib -> (Type -> IO a) -> IO (MapType a)
forall a. TyConLib -> (Type -> IO a) -> IO (MapType a)
mkMTIO TyConLib
tcl (\Type
t1 -> Type -> IO a
lazyf (Type
t0 Type -> Type -> Type
:-> Type
t1))) else TypeName -> Type -> IO (MapType a)
forall a. HasCallStack => TypeName -> a
error TypeName
"mkMTIO': the kind of functions must always be *"
interleaveActions :: [IO a] -> IO [a]
interleaveActions :: [IO a] -> IO [a]
interleaveActions = (IO a -> IO [a] -> IO [a]) -> IO [a] -> [IO a] -> IO [a]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\IO a
x IO [a]
xs -> IO [a] -> IO [a]
forall a. IO a -> IO a
unsafeInterleaveIO ((a -> [a] -> [a]) -> IO a -> IO [a] -> IO [a]
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
Control.Monad.liftM2 (:) IO a
x IO [a]
xs)) ([a] -> IO [a]
forall (m :: * -> *) a. Monad m => a -> m a
return []) ([IO a] -> IO [a]) -> ([IO a] -> [IO a]) -> [IO a] -> IO [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IO a -> IO a) -> [IO a] -> [IO a]
forall a b. (a -> b) -> [a] -> [b]
map IO a -> IO a
forall a. IO a -> IO a
unsafeInterleaveIO
\end{code}