-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree.

{-# LANGUAGE GADTs #-}


module Duckling.Quantity.Helpers
  ( getValue
  , isSimpleQuantity
  , quantity
  , unitOnly
  , valueOnly
  , withProduct
  , withUnit
  , withValue
  , withInterval
  , withMin
  , withMax
  , mkLatent
  ) where

import Data.HashMap.Strict (HashMap)
import Data.Text (Text)
import Prelude
import qualified Data.HashMap.Strict as HashMap
import qualified Data.Text as Text

import Duckling.Dimensions.Types
import Duckling.Quantity.Types (QuantityData(..))
import Duckling.Types
import qualified Duckling.Quantity.Types as TQuantity

getValue :: HashMap Text (Double -> Double) -> Text -> Double -> Double
getValue :: HashMap Text (Double -> Double) -> Text -> Double -> Double
getValue HashMap Text (Double -> Double)
opsMap Text
match = (Double -> Double)
-> Text -> HashMap Text (Double -> Double) -> Double -> Double
forall k v. (Eq k, Hashable k) => v -> k -> HashMap k v -> v
HashMap.lookupDefault Double -> Double
forall a. a -> a
id (Text -> Text
Text.toLower Text
match) HashMap Text (Double -> Double)
opsMap

-- -----------------------------------------------------------------
-- Patterns

isSimpleQuantity :: Predicate
isSimpleQuantity :: Predicate
isSimpleQuantity (Token Dimension a
Quantity QuantityData {TQuantity.unit = Just _
                                              , TQuantity.value = Just _})
 = Bool
True
isSimpleQuantity Token
_ = Bool
False

-- -----------------------------------------------------------------
-- Production

quantity :: TQuantity.Unit -> Double -> QuantityData
quantity :: Unit -> Double -> QuantityData
quantity Unit
u Double
v = QuantityData :: Maybe Unit
-> Maybe Double
-> Maybe Text
-> Maybe Double
-> Maybe Double
-> Bool
-> QuantityData
QuantityData {unit :: Maybe Unit
TQuantity.unit = Unit -> Maybe Unit
forall a. a -> Maybe a
Just Unit
u
                            , value :: Maybe Double
TQuantity.value = Double -> Maybe Double
forall a. a -> Maybe a
Just Double
v
                            , aproduct :: Maybe Text
TQuantity.aproduct = Maybe Text
forall a. Maybe a
Nothing
                            , minValue :: Maybe Double
TQuantity.minValue = Maybe Double
forall a. Maybe a
Nothing
                            , maxValue :: Maybe Double
TQuantity.maxValue = Maybe Double
forall a. Maybe a
Nothing
                            , latent :: Bool
TQuantity.latent = Bool
False}

unitOnly :: TQuantity.Unit -> QuantityData
unitOnly :: Unit -> QuantityData
unitOnly Unit
u = QuantityData :: Maybe Unit
-> Maybe Double
-> Maybe Text
-> Maybe Double
-> Maybe Double
-> Bool
-> QuantityData
QuantityData {unit :: Maybe Unit
TQuantity.unit = Unit -> Maybe Unit
forall a. a -> Maybe a
Just Unit
u
                          , value :: Maybe Double
TQuantity.value = Maybe Double
forall a. Maybe a
Nothing
                          , aproduct :: Maybe Text
TQuantity.aproduct = Maybe Text
forall a. Maybe a
Nothing
                          , minValue :: Maybe Double
TQuantity.minValue = Maybe Double
forall a. Maybe a
Nothing
                          , maxValue :: Maybe Double
TQuantity.maxValue = Maybe Double
forall a. Maybe a
Nothing
                          , latent :: Bool
TQuantity.latent = Bool
False}

valueOnly :: Double -> QuantityData
valueOnly :: Double -> QuantityData
valueOnly Double
v = QuantityData :: Maybe Unit
-> Maybe Double
-> Maybe Text
-> Maybe Double
-> Maybe Double
-> Bool
-> QuantityData
QuantityData {unit :: Maybe Unit
TQuantity.unit = Maybe Unit
forall a. Maybe a
Nothing
                          , value :: Maybe Double
TQuantity.value = Double -> Maybe Double
forall a. a -> Maybe a
Just Double
v
                          , aproduct :: Maybe Text
TQuantity.aproduct = Maybe Text
forall a. Maybe a
Nothing
                          , minValue :: Maybe Double
TQuantity.minValue = Maybe Double
forall a. Maybe a
Nothing
                          , maxValue :: Maybe Double
TQuantity.maxValue = Maybe Double
forall a. Maybe a
Nothing
                          , latent :: Bool
TQuantity.latent = Bool
False}

withProduct :: Text -> QuantityData -> QuantityData
withProduct :: Text -> QuantityData -> QuantityData
withProduct Text
p QuantityData
qd = QuantityData
qd {aproduct :: Maybe Text
TQuantity.aproduct = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
p}

withUnit :: TQuantity.Unit -> QuantityData -> QuantityData
withUnit :: Unit -> QuantityData -> QuantityData
withUnit Unit
u QuantityData
qd = QuantityData
qd {unit :: Maybe Unit
TQuantity.unit = Unit -> Maybe Unit
forall a. a -> Maybe a
Just Unit
u}

withValue :: Double -> QuantityData -> QuantityData
withValue :: Double -> QuantityData -> QuantityData
withValue Double
value QuantityData
qd = QuantityData
qd {value :: Maybe Double
TQuantity.value = Double -> Maybe Double
forall a. a -> Maybe a
Just Double
value}

withInterval :: (Double, Double) -> QuantityData -> QuantityData
withInterval :: (Double, Double) -> QuantityData -> QuantityData
withInterval (Double
from, Double
to) QuantityData
qd = QuantityData
qd {minValue :: Maybe Double
minValue = Double -> Maybe Double
forall a. a -> Maybe a
Just Double
from, maxValue :: Maybe Double
maxValue = Double -> Maybe Double
forall a. a -> Maybe a
Just Double
to}

withMin :: Double -> QuantityData -> QuantityData
withMin :: Double -> QuantityData -> QuantityData
withMin Double
from QuantityData
qd = QuantityData
qd {minValue :: Maybe Double
minValue = Double -> Maybe Double
forall a. a -> Maybe a
Just Double
from}

withMax :: Double -> QuantityData -> QuantityData
withMax :: Double -> QuantityData -> QuantityData
withMax Double
to QuantityData
qd = QuantityData
qd {maxValue :: Maybe Double
maxValue = Double -> Maybe Double
forall a. a -> Maybe a
Just Double
to}

mkLatent :: QuantityData -> QuantityData
mkLatent :: QuantityData -> QuantityData
mkLatent QuantityData
qd = QuantityData
qd {latent :: Bool
TQuantity.latent = Bool
True}