1- {-# LANGUAGE DeriveFunctor , FlexibleContexts, FlexibleInstances, LambdaCase, OverloadedStrings, RecordWildCards, ScopedTypeVariables, TypeApplications #-}
1+ {-# LANGUAGE DeriveGeneric, DeriveTraversable , FlexibleContexts, FlexibleInstances, LambdaCase, OverloadedStrings, RecordWildCards, ScopedTypeVariables, TypeApplications #-}
22module Analysis.Typecheck
33( Monotype (.. )
44, Meta
55, Polytype (PForAll , PBool , PFree , PArr )
66, Scope
7- , Analysis.Typecheck. bind
8- , Analysis.Typecheck. instantiate
97, typecheckingFlowInsensitive
108, typecheckingAnalysis
119) where
1210
1311import Analysis.Eval
1412import Analysis.FlowInsensitive
1513import Control.Applicative (Alternative (.. ))
16- import Control.Effect
14+ import Control.Effect.Carrier
1715import Control.Effect.Fail
1816import Control.Effect.Fresh as Fresh
1917import Control.Effect.Reader hiding (Local )
2018import Control.Effect.State
2119import Control.Monad (unless )
20+ import Control.Monad.Module
2221import qualified Data.Core as Core
2322import Data.File
2423import Data.Foldable (foldl' , for_ )
@@ -30,9 +29,11 @@ import Data.List.NonEmpty (nonEmpty)
3029import Data.Loc
3130import qualified Data.Map as Map
3231import Data.Name as Name
32+ import Data.Scope
3333import qualified Data.Set as Set
3434import Data.Stack
3535import Data.Term
36+ import GHC.Generics (Generic1 )
3637import Prelude hiding (fail )
3738
3839data Monotype a
@@ -47,31 +48,40 @@ data Monotype a
4748
4849type Meta = Int
4950
50- data Polytype
51- = PForAll Scope
51+ data Polytype f a
52+ = PForAll ( Scope () f a )
5253 | PUnit
5354 | PBool
5455 | PString
5556 | PBound Int
5657 | PFree Gensym
57- | PArr Polytype Polytype
58- | PRecord (Map. Map User Polytype )
59- deriving (Eq , Ord , Show )
60-
61- newtype Scope = Scope Polytype
62- deriving (Eq , Ord , Show )
63-
64- forAll :: Gensym -> Polytype -> Polytype
65- forAll n body = PForAll (Analysis.Typecheck. bind n body)
66-
67- forAlls :: Foldable t => t Gensym -> Polytype -> Polytype
58+ | PArr (f a ) (f a )
59+ | PRecord (Map. Map User (f a ))
60+ deriving (Foldable , Functor , Generic1 , Traversable )
61+
62+ instance HFunctor Polytype
63+ instance RightModule Polytype where
64+ PForAll b >>=* f = PForAll (b >>=* f)
65+ PUnit >>=* _ = PUnit
66+ PBool >>=* _ = PBool
67+ PString >>=* _ = PString
68+ PBound i >>=* _ = PBound i
69+ PFree n >>=* _ = PFree n
70+ PArr a b >>=* f = PArr (a >>= f) (b >>= f)
71+ PRecord m >>=* f = PRecord ((>>= f) <$> m)
72+
73+
74+ forAll :: (Eq a , Carrier sig m , Member Polytype sig ) => a -> m a -> m a
75+ forAll n body = send (PForAll (Data.Scope. bind1 n body))
76+
77+ forAlls :: (Eq a , Carrier sig m , Member Polytype sig , Foldable t ) => t a -> m a -> m a
6878forAlls ns body = foldr forAll body ns
6979
70- generalize :: (Carrier sig m , Member Naming sig ) => Monotype Meta -> m Polytype
80+ generalize :: (Carrier sig m , Member Naming sig ) => Monotype Meta -> m ( Term Polytype Gensym )
7181generalize ty = namespace " generalize" $ do
7282 Gensym root _ <- Name. fresh
7383 pure (forAlls (map (Gensym root) (IntSet. toList (mvs ty))) (fold root ty))
74- where fold root = \ case
84+ where fold root = Term . \ case
7585 MUnit -> PUnit
7686 MBool -> PBool
7787 MString -> PString
@@ -80,30 +90,8 @@ generalize ty = namespace "generalize" $ do
8090 MArr a b -> PArr (fold root a) (fold root b)
8191 MRecord fs -> PRecord (fold root <$> fs)
8292
83- -- | Bind occurrences of a 'Gensym' in a 'Polytype' term, producing a 'Scope' in which the 'Gensym' is bound.
84- bind :: Gensym -> Polytype -> Scope
85- bind name = Scope . substIn (\ i n -> if name == n then PBound i else PFree n) (const PBound )
86-
87- -- | Substitute a 'Polytype' term for the free variable in a given 'Scope', producing a closed 'Polytype' term.
88- instantiate :: Polytype -> Scope -> Polytype
89- instantiate image (Scope body) = substIn (const PFree ) (\ i j -> if i == j then image else PBound j) body
90-
91- substIn :: (Int -> Gensym -> Polytype )
92- -> (Int -> Int -> Polytype )
93- -> Polytype
94- -> Polytype
95- substIn free bound = go 0
96- where go i (PFree name) = free i name
97- go i (PBound j) = bound i j
98- go i (PForAll (Scope body)) = PForAll (Scope (go (succ i) body))
99- go _ PUnit = PUnit
100- go _ PBool = PBool
101- go _ PString = PString
102- go i (PArr a b) = PArr (go i a) (go i b)
103- go i (PRecord fs) = PRecord (go i <$> fs)
104-
105-
106- typecheckingFlowInsensitive :: [File (Term Core. Core Name )] -> (Heap Name (Monotype Meta ), [File (Either (Loc , String ) Polytype )])
93+
94+ typecheckingFlowInsensitive :: [File (Term Core. Core Name )] -> (Heap Name (Monotype Meta ), [File (Either (Loc , String ) (Term Polytype Gensym ))])
10795typecheckingFlowInsensitive
10896 = run
10997 . runFresh
0 commit comments