-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHoogle.hs
82 lines (71 loc) · 2.18 KB
/
Hoogle.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
module Search.Hoogle
( Popularity (..),
hoogleFingerprint,
hoogle,
)
where
import Data.Foldable (toList)
import Data.List (sortOn)
import Data.Monoid (Sum (Sum, getSum))
import Data.Word (Word8)
import Search (SearchLimit (SearchLimit))
import qualified Search.Structured as S
-- minBound meaning least popular
-- maxBound meaning most popular
newtype Popularity
= Popularity Word8
deriving (Eq, Ord, Show, Bounded)
scalePopularity :: Popularity -> Double
scalePopularity (Popularity n) =
fromIntegral n / fromIntegral (maxBound :: Word8)
fingerprintCost :: (n -> Popularity) -> S.FingerprintCost n -> Int
fingerprintCost popularity (S.FingerprintCost ac tc rc) =
arityCost ac + termsCost tc + rareCost popularity rc
arityCost :: S.FingerprintArityCost -> Int
arityCost S.FingerprintAritySame =
0
arityCost S.FingerprintArityOneMore =
1000
arityCost S.FingerprintArityOneLess =
300
arityCost S.FingerprintArityTwoLess =
900
termsCost :: S.FingerprintTermsCost -> Int
termsCost S.FingerprintTermsSame =
0
termsCost (S.FingerprintTermsDifferent w) =
fromIntegral w
rareCost :: (n -> Popularity) -> S.FingerprintRareCost n -> Int
rareCost popularity (S.FingerprintRareCost a b) =
getSum (foldMap (f 5000 400) a <> foldMap (f 1000 50) b)
where
f common rare s =
let p =
scalePopularity (popularity s)
common' =
p * common
rare' =
(1 - p) * rare
in Sum (floor (common' + rare'))
signatureCost :: S.SignatureCost -> Int
signatureCost (S.SignatureCost uc) =
signatureUnificationCost uc
signatureUnificationCost :: S.SignatureUnificationCost -> Int
signatureUnificationCost (S.SignatureUnificationCost uc) =
fromIntegral uc
hoogleFingerprint :: (a -> Popularity) -> S.Signature a -> S.Fingerprint a
hoogleFingerprint f signature@(S.Signature ts) =
S.Fingerprint rare (fromIntegral (length terms)) (fromIntegral arity)
where
rare =
take 3 (sortOn f terms)
terms =
toList signature
arity =
length ts - 1
hoogle ::
(Ord a, Ord n) =>
(a -> Popularity) ->
S.StructuredSearch a n
hoogle popularity =
S.structuredSearch (SearchLimit 100) (fingerprintCost popularity) signatureCost