5import Control.Arrow (second)
6import Control.Monad (liftM)
7import Data.List (foldl')
8import qualified Data.Set as Set
12import Control.DeepSeq (NFData (..), deepseq)
14unify hints expr = run $ do
15 cs <- constrain hints expr
18solver [] subs = return $ Right subs
20-------- Destruct Type-constructors --------
22solver ((t1@(ADT n1 ts1) :=: t2@(ADT n2 ts2)) : cs) subs =
23 if n1 /= n2 then uniError t1 t2 else
24 solver (zipWith (:=:) ts1 ts2 ++ cs) subs
25solver ((LambdaT t1 t2 :=: LambdaT t1' t2') : cs) subs =
26 solver ([ t1 :=: t1', t2 :=: t2' ] ++ cs) subs
28-------- Type-equality --------
30solver ((VarT x :=: t) : cs) subs =
31 solver (map (cSub x t) cs) . map (second $ tSub x t) $ (x,t):subs
32solver ((t :=: VarT x) : cs) subs =
33 solver (map (cSub x t) cs) . map (second $ tSub x t) $ (x,t):subs
34solver ((t1 :=: t2) : cs) subs =
35 if t1 /= t2 then uniError t1 t2 else solver cs subs
37-------- subtypes --------
39solver ((t1 :<: t2) : cs) subs = do
40 let f x = do y <- guid ; return (x,VarT y)
41 pairs <- mapM f . Set.toList $ getVars t2
42 let t2' = foldr (uncurry tSub) t2 pairs
43 solver ((t1 :=: t2') : cs) subs
46cSub k v (t1 :=: t2) = force $ tSub k v t1 :=: tSub k v t2
47cSub k v (t1 :<: t2) = force $ tSub k v t1 :<: tSub k v t2
49tSub k v t@(VarT x) = if k == x then v else t
50tSub k v (LambdaT t1 t2) = force $ LambdaT (tSub k v t1) (tSub k v t2)
51tSub k v (ADT name ts) = ADT name (map (force . tSub k v) ts)
54getVars (VarT x) = Set.singleton x
55getVars (LambdaT t1 t2) = Set.union (getVars t1) (getVars t2)
56getVars (ADT name ts) = Set.unions $ map getVars ts
60 return . Left $ "Type error: " ++ show t1 ++ " is not equal to " ++ show t2
62force x = x `deepseq` x
64instance NFData Constraint where
65 rnf (t1 :=: t2) = t1 `deepseq` t2 `deepseq` ()
66 rnf (t1 :<: t2) = t1 `deepseq` t2 `deepseq` ()
68instance NFData Type where
69 rnf (LambdaT t1 t2) = t1 `deepseq` t2 `deepseq` ()
70 rnf (ADT _ ts) = foldl' (\acc x -> x `deepseq` acc) () ts
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list