@@ -19,7 +19,8 @@ import Control.Monad.Trans.Reader (runReaderT)
1919import qualified Data.Aeson as A
2020import Data.Aeson ((.=) )
2121import qualified Data.ByteString.Lazy as BL
22- import Data.List (foldl' )
22+ import Data.Function (on )
23+ import Data.List (foldl' , nubBy )
2324import qualified Data.Map as M
2425import Data.String (fromString )
2526import Data.Text (Text )
@@ -98,37 +99,48 @@ server bundled externs initEnv port = do
9899 Scotty. json $ A. object [ " js" .= comp ]
99100 get " /search" $ do
100101 query <- param " q"
102+ Scotty. setHeader " Access-Control-Allow-Origin" " *"
103+ Scotty. setHeader " Content-Type" " application/json"
101104 case tryParseType query of
102105 Nothing -> Scotty. json $ A. object [ " error" .= (" Cannot parse type" :: Text ) ]
103106 Just ty -> do
104- let ty' = replaceTypeVariablesAndDesugar ty
105- let results = TS. typeSearch (Just [] ) initEnv (P. emptyCheckState initEnv) ty'
106- Scotty. json $ A. object [ " results" .= A. object [ P. showQualified P. runIdent k .= P. prettyPrintType v
107- | (k, v) <- take 20 (M. toList results)
108- ]
107+ let elabs = lookupAllConstructors initEnv ty
108+ search = M. toList . TS. typeSearch (Just [] ) initEnv (P. emptyCheckState initEnv)
109+ results = nubBy ((==) `on` fst ) $ do
110+ elab <- elabs
111+ let strictMatches = search (replaceTypeVariablesAndDesugar (\ nm s -> P. Skolem nm s (P. SkolemScope 0 ) Nothing ) elab)
112+ flexMatches = search (replaceTypeVariablesAndDesugar (const P. TUnknown ) elab)
113+ take 50 (strictMatches ++ flexMatches)
114+ Scotty. json $ A. object [ " results" .= [ P. showQualified P. runIdent k
115+ | (k, _) <- take 50 results
116+ ]
109117 ]
110118
119+ lookupAllConstructors :: P. Environment -> P. Type -> [P. Type ]
120+ lookupAllConstructors env = P. everywhereOnTypesM $ \ case
121+ P. TypeConstructor (P. Qualified Nothing tyCon) -> P. TypeConstructor <$> lookupConstructor env tyCon
122+ other -> pure other
123+ where
124+ lookupConstructor :: P. Environment -> P. ProperName 'P.TypeName -> [P. Qualified (P. ProperName 'P.TypeName )]
125+ lookupConstructor env nm =
126+ [ q
127+ | (q@ (P. Qualified (Just mn) thisNm), _) <- M. toList (P. types env)
128+ , thisNm == nm
129+ ]
130+
111131-- | (Consistently) replace unqualified type constructors and type variables with unknowns.
112132--
113133-- Also remove the @ParensInType@ Constructor (we need to deal with type operators later at some point).
114- replaceTypeVariablesAndDesugar :: P. Type -> P. Type
115- replaceTypeVariablesAndDesugar ty = State. evalState (P. everywhereOnTypesM go ty) (0 , M. empty) where
134+ replaceTypeVariablesAndDesugar :: ( Text -> Int -> P. Type ) -> P. Type -> P. Type
135+ replaceTypeVariablesAndDesugar f ty = State. evalState (P. everywhereOnTypesM go ty) (0 , M. empty) where
116136 go = \ case
117137 P. ParensInType ty -> pure ty
118- P. TypeConstructor (P. Qualified Nothing tyCon) -> do
119- (next, m) <- State. get
120- case M. lookup (Left tyCon) m of
121- Nothing -> do
122- let ty = P. TUnknown next
123- State. put (next + 1 , M. insert (Left tyCon) ty m)
124- pure ty
125- Just ty -> pure ty
126138 P. TypeVar s -> do
127139 (next, m) <- State. get
128- case M. lookup ( Right s) m of
140+ case M. lookup s m of
129141 Nothing -> do
130- let ty = P. TUnknown next
131- State. put (next + 1 , M. insert ( Right s) ty m)
142+ let ty = f s next
143+ State. put (next + 1 , M. insert s ty m)
132144 pure ty
133145 Just ty -> pure ty
134146 other -> pure other
0 commit comments