@@ -726,7 +726,6 @@ tc (UForall _ forallLoc _ _ fall _ _ reps0) _env = go reps0 fall
726726 go [] (Term typed') = pure typed'
727727 go (SomeTypeRep rep : reps) (Forall sym f)
728728 | Just Type. HRefl <- Type. eqTypeRep (typeRepKind rep) sym = go reps (f rep)
729- -- Cases that look like: Monad (Either (a :: Type) :: Type -> Type)
730729 go reps (ClassConstraint rep crep f) =
731730 withClassConstraint forallLoc reps rep crep f go
732731 go reps fa@ (GetOf k0 a0 t0 r0 f) =
@@ -768,30 +767,9 @@ withClassConstraint ::
768767 ([SomeTypeRep ] -> Forall -> Either TypeCheckError (Typed (Term g ))) ->
769768 Either TypeCheckError (Typed (Term g ))
770769withClassConstraint forallLoc reps rep crep f go =
771- if
772- -- Cases that look like: Semigroup (Vector (e :: *))
773- -- Note: the kinds are limited to this exact specification in the signature above.
774- | Type. App t _ <- rep,
775- Just Type. HRefl <- Type. eqTypeRep (typeRepKind t) (TypeRep @ (Type -> Type )),
776- Just dict <- resolve1 (Type. App crep rep) crep t instances ->
777- go reps (withDict dict f)
778- -- Cases that look like: Monad (Either (e :: *) (a :: *))
779- -- Note: the kinds are limited to this exact specification in the signature above.
780- | Type. App t _ <- rep,
781- Just Type. HRefl <- Type. eqTypeRep (typeRepKind t) (TypeRep @ (Type -> Type -> Type )),
782- Just dict <- resolve1 (Type. App crep rep) crep t instances ->
783- go reps (withDict dict f)
784- -- Cases that look like: Semigroup (Mod (f :: * -> *) (a :: *))
785- -- Note: the kinds are limited to this exact specification in the signature above.
786- | Type. App (Type. App t _a) _b <- rep,
787- Just Type. HRefl <- Type. eqTypeRep (typeRepKind t) (TypeRep @ ((Type -> Type ) -> Type -> Type )),
788- Just dict <- resolve2 (Type. App crep rep) crep t instances ->
789- go reps (withDict dict f)
790- -- Simple cases: Eq (a :: k)
791- | Just dict <- resolve crep rep instances ->
792- go reps (withDict dict f)
793- | otherwise ->
794- problem $
770+ case lookupDict rep crep of
771+ Just dict -> go reps (withDict dict f)
772+ Nothing -> problem $
795773 " type "
796774 ++ show rep
797775 ++ " doesn't appear to be an instance of "
@@ -800,20 +778,60 @@ withClassConstraint forallLoc reps rep crep f go =
800778 problem :: forall x . String -> Either TypeCheckError x
801779 problem = Left . ConstraintResolutionProblem forallLoc (ClassConstraint rep crep f)
802780
781+ -- The workhorse behind withClassConstraint. See documentation there.
782+ lookupDict ::
783+ forall g k (c :: k -> Constraint ) (a :: k ).
784+ TypeRep a ->
785+ TypeRep c ->
786+ Maybe (Dict (c a ))
787+ lookupDict rep crep =
788+ if
789+ -- Cases that look like: Semigroup (Vector (e :: *))
790+ -- Note: the kinds are limited to this exact specification in the signature above.
791+ | Type. App t _ <- rep,
792+ Just Type. HRefl <- Type. eqTypeRep (typeRepKind t) (TypeRep @ (Type -> Type )),
793+ Just dict <- resolve1 (Type. App crep rep) crep t instances ->
794+ pure dict
795+ -- Cases that look like: Monad (Either (e :: *) (a :: *))
796+ -- Note: the kinds are limited to this exact specification in the signature above.
797+ | Type. App t _ <- rep,
798+ Just Type. HRefl <- Type. eqTypeRep (typeRepKind t) (TypeRep @ (Type -> Type -> Type )),
799+ Just dict <- resolve1 (Type. App crep rep) crep t instances ->
800+ pure dict
801+ -- Cases that look like: Semigroup (Mod (f :: * -> *) (a :: *))
802+ -- Note: the kinds are limited to this exact specification in the signature above.
803+ | Type. App (Type. App t _a) _b <- rep,
804+ Just Type. HRefl <- Type. eqTypeRep (typeRepKind t) (TypeRep @ ((Type -> Type ) -> Type -> Type )),
805+ Just dict <- resolve2 (Type. App crep rep) crep t instances ->
806+ pure dict
807+ -- Simple cases: Eq (a :: k)
808+ | otherwise ->
809+ resolve crep rep instances
810+
803811--------------------------------------------------------------------------------
804812-- Instances
805813
814+ -- Dict but for (t :: * -> *), like Monad []
806815newtype D1 c t = D1 (forall e . Dict (c (t e )))
807816
817+ -- Dict but for (t :: * -> * -> *), like Monad (Either e)
808818newtype D2 c t = D2 (forall f a . Dict (c (t f a )))
809819
810- newtype Instances = Instances (Map (SomeTypeRep , SomeTypeRep ) Dynamic )
820+ -- Entailment, c a => c (t a), E.g. Eq a :- Eq [a]
821+ newtype ED1 c t = ED1 (forall e . c e :- c (t e ))
822+
823+ newtype Instances = Instances { getInstances :: Map (SomeTypeRep , SomeTypeRep ) Dynamic }
811824
812825instances :: Instances
813826instances =
814827 Instances $
815828 Map. fromList
816- [ instance0 @ Show @ Int ,
829+ [ entail1 @ Show @ [] ,
830+ entail1 @ Show @ Set ,
831+ entail1 @ Show @ Tree ,
832+ entail1 @ Show @ Maybe ,
833+ entail1 @ Show @ Vector ,
834+ instance0 @ Show @ Int ,
817835 instance0 @ Show @ Integer ,
818836 instance0 @ Show @ Day ,
819837 instance0 @ Show @ UTCTime ,
@@ -824,6 +842,12 @@ instances =
824842 instance0 @ Show @ Text ,
825843 instance0 @ Show @ ByteString ,
826844 instance0 @ Show @ ExitCode ,
845+ instance0 @ Show @ Value ,
846+ entail1 @ Eq @ [] ,
847+ entail1 @ Eq @ Set ,
848+ entail1 @ Eq @ Maybe ,
849+ entail1 @ Eq @ Tree ,
850+ entail1 @ Eq @ Vector ,
827851 instance0 @ Eq @ Int ,
828852 instance0 @ Eq @ Integer ,
829853 instance0 @ Eq @ Day ,
@@ -835,6 +859,11 @@ instances =
835859 instance0 @ Eq @ Text ,
836860 instance0 @ Eq @ ByteString ,
837861 instance0 @ Eq @ ExitCode ,
862+ entail1 @ Ord @ [] ,
863+ entail1 @ Ord @ Set ,
864+ entail1 @ Ord @ Maybe ,
865+ entail1 @ Ord @ Tree ,
866+ entail1 @ Ord @ Vector ,
838867 instance0 @ Ord @ Int ,
839868 instance0 @ Ord @ Integer ,
840869 instance0 @ Ord @ Day ,
@@ -865,6 +894,7 @@ instances =
865894 instance1 @ Applicative @ Either ,
866895 instance0 @ Alternative @ Options. Parser ,
867896 instance0 @ Alternative @ Maybe ,
897+ entail1 @ Semigroup @ Maybe ,
868898 instance0 @ Monoid @ Text ,
869899 instance1 @ Monoid @ Vector ,
870900 instance2 @ Monoid @ Options. Mod ,
@@ -896,6 +926,30 @@ instance1 =
896926 toDyn $ D1 @ c @ t Dict
897927 )
898928
929+ -- A very restricted kind of entailment: C a => C (t a)
930+ -- This serves:
931+ -- Eq a => Eq [a], Ord a => Ord (Maybe [a]), etc.
932+ --
933+ -- Lookup process:
934+ -- class = Ord
935+ -- type = Maybe [Int]
936+ -- find (Ord,Maybe)
937+ -- recurse
938+ -- find (Ord,[])
939+ -- recurse
940+ -- find (Ord,Int)
941+ -- ==> Ord Int
942+ -- ==> Ord [Int]
943+ -- ==> Ord (Maybe [Int])
944+ entail1 ::
945+ forall {k1 } (c :: k1 -> Constraint ) (t :: k1 -> k1 ).
946+ ((forall a . c a => c (t a )), Typeable c , Typeable t , Typeable k1 ) =>
947+ ((SomeTypeRep , SomeTypeRep ), Dynamic )
948+ entail1 =
949+ ( (SomeTypeRep $ typeRep @ c , SomeTypeRep $ typeRep @ t ),
950+ toDyn $ ED1 @ c @ t (Sub Dict )
951+ )
952+
899953instance2 ::
900954 forall {k0 } {k1 } {k2 } (c :: k2 -> Constraint ) (t :: k0 -> k1 -> k2 ).
901955 ((forall a b . c (t a b )), Typeable c , Typeable t , Typeable k0 , Typeable k1 , Typeable k2 ) =>
@@ -924,11 +978,21 @@ resolve1 ::
924978 TypeRep t ->
925979 Instances ->
926980 Maybe (Dict (c (t a )))
927- resolve1 _ c t (Instances m) = do
981+ resolve1 cta c t (Instances m) = do
928982 Dynamic rep dict <- Map. lookup (SomeTypeRep c, SomeTypeRep t) m
929- Type. HRefl <- Type. eqTypeRep rep $ Type. App (Type. App (typeRep @ D1 ) c) t
930- let D1 d = dict
931- pure d
983+ (do Type. HRefl <- Type. eqTypeRep rep $ Type. App (Type. App (typeRep @ D1 ) c) t
984+ let D1 d = dict
985+ pure d) <|>
986+ -- When we see e.g. C (T A), where T A and A have the same kind,
987+ -- we can lookup C A, for the entailment C A :- C (T A).
988+ (do case cta of
989+ Type. App _c a@ (Type. App f a') -> do
990+ Type. HRefl <- Type. eqTypeRep (typeRepKind a') (typeRepKind a)
991+ Type. HRefl <- Type. eqTypeRep rep $ Type. App (Type. App (typeRep @ ED1 ) c) f
992+ let ED1 entailment = dict
993+ dictA <- lookupDict a' c
994+ pure $ mapDict entailment dictA
995+ _ -> Nothing )
932996
933997-- Resolve an instance of the form: Monoid (Mod f a)
934998resolve2 ::
@@ -2996,6 +3060,9 @@ _generateApiDocs = do
29963060 let excludeHidden = filter (not . List. isPrefixOf " hell:Hell." . fst )
29973061 ul_ do
29983062 for_ (excludeHidden $ Map. toList supportedTypeConstructors) typeConsToHtml
3063+ h2_ " Instances"
3064+ ul_ do
3065+ for_ (Map. toList instances. getInstances) instToHtml
29993066 h2_ " Terms"
30003067 let groups =
30013068 excludeHidden $
@@ -3052,6 +3119,38 @@ makeSearchIndex = Json.Array $ typeConstructorsIndex <> litsIndex <> polysIndex
30523119nameToElementId :: String -> Text
30533120nameToElementId = Text. pack
30543121
3122+ instToHtml :: ((SomeTypeRep , SomeTypeRep ), Dynamic ) -> Html ()
3123+ instToHtml ((cls', ty), dyn') =
3124+ li_ [id_ (nameToElementId name), class_ " searchable" ] $ do
3125+ code_ do
3126+ em_ " instance "
3127+ when entailed do
3128+ strong_ do
3129+ " ("
3130+ toHtml $ show cls'
3131+ " a) => "
3132+ strong_ $ toHtml $ show cls'
3133+ " "
3134+ if entailed || foralld
3135+ then strong_ do
3136+ " ("
3137+ toHtml $ show ty
3138+ " a)"
3139+ else
3140+ if foralld2
3141+ then strong_ do
3142+ " ("
3143+ toHtml $ show ty
3144+ " a b)"
3145+ else
3146+ strong_ $ toHtml $ show ty
3147+
3148+ where name = show cls' ++ " " ++ show ty
3149+ -- TODO: Use the types rather than this hack.
3150+ entailed = Text. isPrefixOf " <<ED1" (Text. pack (show dyn'))
3151+ foralld = Text. isPrefixOf " <<D1" (Text. pack (show dyn'))
3152+ foralld2 = Text. isPrefixOf " <<D2" (Text. pack (show dyn'))
3153+
30553154typeConsToHtml :: (String , SomeTypeRep ) -> Html ()
30563155typeConsToHtml (name, SomeTypeRep rep) =
30573156 li_ [id_ (nameToElementId name), class_ " searchable" ] $ do
0 commit comments