Skip to content

Commit a99d0f3

Browse files
committed
Replace type constructors first, prefer strict matches
1 parent b16928c commit a99d0f3

File tree

1 file changed

+31
-19
lines changed

1 file changed

+31
-19
lines changed

server/Main.hs

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ import Control.Monad.Trans.Reader (runReaderT)
1919
import qualified Data.Aeson as A
2020
import Data.Aeson ((.=))
2121
import qualified Data.ByteString.Lazy as BL
22-
import Data.List (foldl')
22+
import Data.Function (on)
23+
import Data.List (foldl', nubBy)
2324
import qualified Data.Map as M
2425
import Data.String (fromString)
2526
import 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

Comments
 (0)