{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE OverloadedStrings #-} -- ---------------------------------------------------------------------------- {- | Common types used within Hunt. -} -- ---------------------------------------------------------------------------- module Hunt.Common.BasicTypes ( module Hunt.Common.BasicTypes , Monoid(..) , (<>) ) where import Control.Applicative import Control.Monad (mzero) import Control.DeepSeq import Data.Aeson import Data.Binary hiding (Word) import Data.Map import Data.Monoid (Monoid (..), (<>)) import Data.Text import Hunt.Common.DocDesc (DocDesc) import Prelude as P -- ------------------------------------------------------------ -- | The URI describing the location of the original document. type URI = Text -- | The description of a document is a generic key value map. type Description = DocDesc -- | The title of a document. type Title = Text -- | The content of a document. type Content = Text -- | The position of a word in the document. type Position = Int -- | The name of a context. type Context = Text -- | A single word. type Word = Text -- | Positions of Words for each context. type Words = Map Context WordList -- | Positions of words in the document. type WordList = Map Word [Position] -- | Text index data TextSearchOp = Case | NoCase | PrefixCase | PrefixNoCase deriving (Eq, Show) -- | Weight (for ranking). type Weight = Score -- | Regular expression. type RegEx = Text -- | The score of a hit (either a document hit or a word hit). -- type Score = Float -- ------------------------------------------------------------ -- | Weight or score of a documents, -- @0.0@ indicates: not set, so there is no need to work with Maybe's -- wrapped in newtype to not mix up with Score's and Weight's in documents newtype Score = SC {unScore :: Float} deriving (Eq, Ord, Num, Fractional, Show) instance NFData Score where rnf (SC f) = f `seq` () noScore :: Score noScore = SC 0.0 mkScore :: Float -> Score mkScore x | x > 0.0 = SC x | otherwise = noScore getScore :: Score -> Maybe Float getScore (SC 0.0) = Nothing getScore (SC x ) = Just x defScore :: Score defScore = SC 1.0 toDefScore :: Score -> Score toDefScore (SC 0.0) = defScore toDefScore sc = sc fromDefScore :: Score -> Score fromDefScore (SC 1.0) = noScore fromDefScore sc = sc accScore :: [Score] -> Score accScore [] = defScore accScore xs = mkScore $ sum (P.map unScore xs) / fromIntegral (P.length xs) -- the Monoid instance is used to accumulate scores -- in query results, so tune it here when sum is not appropriate instance Monoid Score where mempty = noScore mappend = (+) -- ------------------------------------------------------------ -- JSON instances -- ------------------------------------------------------------ instance FromJSON Score where parseJSON x = mkScore <$> parseJSON x instance ToJSON Score where toJSON (SC x) = toJSON x instance FromJSON TextSearchOp where parseJSON (String s) = case s of "case" -> return Case "noCase" -> return NoCase "prefixCase" -> return PrefixCase "prefixNoCase" -> return PrefixNoCase _ -> mzero parseJSON _ = mzero instance ToJSON TextSearchOp where toJSON o = case o of Case -> "case" NoCase -> "noCase" PrefixCase -> "prefixCase" PrefixNoCase -> "prefixNoCase" -- ------------------------------------------------------------ -- Binary instances -- ------------------------------------------------------------ instance Binary Score where put (SC x) = put x get = SC <$> get instance Binary TextSearchOp where put (Case) = put (0 :: Word8) put (NoCase) = put (1 :: Word8) put (PrefixCase) = put (2 :: Word8) put (PrefixNoCase) = put (3 :: Word8) get = do t <- get :: Get Word8 case t of 0 -> return Case 1 -> return NoCase 2 -> return PrefixCase 3 -> return PrefixNoCase _ -> fail "enum out of bounds: TextSearchOp" -- ------------------------------------------------------------