-- 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 DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE NoRebindableSyntax #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}

module Duckling.Temperature.Types where

import Control.DeepSeq
import Data.Aeson
import Data.Hashable
import Data.Text (Text)
import GHC.Generics
import Prelude
import qualified Data.HashMap.Strict as H
import qualified Data.Text as Text

import Duckling.Resolve (Resolve(..))

data TemperatureUnit =
  Degree | Celsius | Fahrenheit
  deriving (TemperatureUnit -> TemperatureUnit -> Bool
(TemperatureUnit -> TemperatureUnit -> Bool)
-> (TemperatureUnit -> TemperatureUnit -> Bool)
-> Eq TemperatureUnit
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TemperatureUnit -> TemperatureUnit -> Bool
$c/= :: TemperatureUnit -> TemperatureUnit -> Bool
== :: TemperatureUnit -> TemperatureUnit -> Bool
$c== :: TemperatureUnit -> TemperatureUnit -> Bool
Eq, (forall x. TemperatureUnit -> Rep TemperatureUnit x)
-> (forall x. Rep TemperatureUnit x -> TemperatureUnit)
-> Generic TemperatureUnit
forall x. Rep TemperatureUnit x -> TemperatureUnit
forall x. TemperatureUnit -> Rep TemperatureUnit x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep TemperatureUnit x -> TemperatureUnit
$cfrom :: forall x. TemperatureUnit -> Rep TemperatureUnit x
Generic, Int -> TemperatureUnit -> Int
TemperatureUnit -> Int
(Int -> TemperatureUnit -> Int)
-> (TemperatureUnit -> Int) -> Hashable TemperatureUnit
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: TemperatureUnit -> Int
$chash :: TemperatureUnit -> Int
hashWithSalt :: Int -> TemperatureUnit -> Int
$chashWithSalt :: Int -> TemperatureUnit -> Int
Hashable, Int -> TemperatureUnit -> ShowS
[TemperatureUnit] -> ShowS
TemperatureUnit -> String
(Int -> TemperatureUnit -> ShowS)
-> (TemperatureUnit -> String)
-> ([TemperatureUnit] -> ShowS)
-> Show TemperatureUnit
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TemperatureUnit] -> ShowS
$cshowList :: [TemperatureUnit] -> ShowS
show :: TemperatureUnit -> String
$cshow :: TemperatureUnit -> String
showsPrec :: Int -> TemperatureUnit -> ShowS
$cshowsPrec :: Int -> TemperatureUnit -> ShowS
Show, Eq TemperatureUnit
Eq TemperatureUnit
-> (TemperatureUnit -> TemperatureUnit -> Ordering)
-> (TemperatureUnit -> TemperatureUnit -> Bool)
-> (TemperatureUnit -> TemperatureUnit -> Bool)
-> (TemperatureUnit -> TemperatureUnit -> Bool)
-> (TemperatureUnit -> TemperatureUnit -> Bool)
-> (TemperatureUnit -> TemperatureUnit -> TemperatureUnit)
-> (TemperatureUnit -> TemperatureUnit -> TemperatureUnit)
-> Ord TemperatureUnit
TemperatureUnit -> TemperatureUnit -> Bool
TemperatureUnit -> TemperatureUnit -> Ordering
TemperatureUnit -> TemperatureUnit -> TemperatureUnit
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: TemperatureUnit -> TemperatureUnit -> TemperatureUnit
$cmin :: TemperatureUnit -> TemperatureUnit -> TemperatureUnit
max :: TemperatureUnit -> TemperatureUnit -> TemperatureUnit
$cmax :: TemperatureUnit -> TemperatureUnit -> TemperatureUnit
>= :: TemperatureUnit -> TemperatureUnit -> Bool
$c>= :: TemperatureUnit -> TemperatureUnit -> Bool
> :: TemperatureUnit -> TemperatureUnit -> Bool
$c> :: TemperatureUnit -> TemperatureUnit -> Bool
<= :: TemperatureUnit -> TemperatureUnit -> Bool
$c<= :: TemperatureUnit -> TemperatureUnit -> Bool
< :: TemperatureUnit -> TemperatureUnit -> Bool
$c< :: TemperatureUnit -> TemperatureUnit -> Bool
compare :: TemperatureUnit -> TemperatureUnit -> Ordering
$ccompare :: TemperatureUnit -> TemperatureUnit -> Ordering
$cp1Ord :: Eq TemperatureUnit
Ord, TemperatureUnit -> ()
(TemperatureUnit -> ()) -> NFData TemperatureUnit
forall a. (a -> ()) -> NFData a
rnf :: TemperatureUnit -> ()
$crnf :: TemperatureUnit -> ()
NFData)

instance ToJSON TemperatureUnit where
  toJSON :: TemperatureUnit -> Value
toJSON = Text -> Value
String (Text -> Value)
-> (TemperatureUnit -> Text) -> TemperatureUnit -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
Text.toLower (Text -> Text)
-> (TemperatureUnit -> Text) -> TemperatureUnit -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
Text.pack (String -> Text)
-> (TemperatureUnit -> String) -> TemperatureUnit -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TemperatureUnit -> String
forall a. Show a => a -> String
show

data TemperatureData = TemperatureData
  { TemperatureData -> Maybe TemperatureUnit
unit     :: Maybe TemperatureUnit
  , TemperatureData -> Maybe Double
value    :: Maybe Double
  , TemperatureData -> Maybe Double
minValue :: Maybe Double
  , TemperatureData -> Maybe Double
maxValue :: Maybe Double
  } deriving (TemperatureData -> TemperatureData -> Bool
(TemperatureData -> TemperatureData -> Bool)
-> (TemperatureData -> TemperatureData -> Bool)
-> Eq TemperatureData
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TemperatureData -> TemperatureData -> Bool
$c/= :: TemperatureData -> TemperatureData -> Bool
== :: TemperatureData -> TemperatureData -> Bool
$c== :: TemperatureData -> TemperatureData -> Bool
Eq, (forall x. TemperatureData -> Rep TemperatureData x)
-> (forall x. Rep TemperatureData x -> TemperatureData)
-> Generic TemperatureData
forall x. Rep TemperatureData x -> TemperatureData
forall x. TemperatureData -> Rep TemperatureData x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep TemperatureData x -> TemperatureData
$cfrom :: forall x. TemperatureData -> Rep TemperatureData x
Generic, Int -> TemperatureData -> Int
TemperatureData -> Int
(Int -> TemperatureData -> Int)
-> (TemperatureData -> Int) -> Hashable TemperatureData
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: TemperatureData -> Int
$chash :: TemperatureData -> Int
hashWithSalt :: Int -> TemperatureData -> Int
$chashWithSalt :: Int -> TemperatureData -> Int
Hashable, Int -> TemperatureData -> ShowS
[TemperatureData] -> ShowS
TemperatureData -> String
(Int -> TemperatureData -> ShowS)
-> (TemperatureData -> String)
-> ([TemperatureData] -> ShowS)
-> Show TemperatureData
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TemperatureData] -> ShowS
$cshowList :: [TemperatureData] -> ShowS
show :: TemperatureData -> String
$cshow :: TemperatureData -> String
showsPrec :: Int -> TemperatureData -> ShowS
$cshowsPrec :: Int -> TemperatureData -> ShowS
Show, Eq TemperatureData
Eq TemperatureData
-> (TemperatureData -> TemperatureData -> Ordering)
-> (TemperatureData -> TemperatureData -> Bool)
-> (TemperatureData -> TemperatureData -> Bool)
-> (TemperatureData -> TemperatureData -> Bool)
-> (TemperatureData -> TemperatureData -> Bool)
-> (TemperatureData -> TemperatureData -> TemperatureData)
-> (TemperatureData -> TemperatureData -> TemperatureData)
-> Ord TemperatureData
TemperatureData -> TemperatureData -> Bool
TemperatureData -> TemperatureData -> Ordering
TemperatureData -> TemperatureData -> TemperatureData
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: TemperatureData -> TemperatureData -> TemperatureData
$cmin :: TemperatureData -> TemperatureData -> TemperatureData
max :: TemperatureData -> TemperatureData -> TemperatureData
$cmax :: TemperatureData -> TemperatureData -> TemperatureData
>= :: TemperatureData -> TemperatureData -> Bool
$c>= :: TemperatureData -> TemperatureData -> Bool
> :: TemperatureData -> TemperatureData -> Bool
$c> :: TemperatureData -> TemperatureData -> Bool
<= :: TemperatureData -> TemperatureData -> Bool
$c<= :: TemperatureData -> TemperatureData -> Bool
< :: TemperatureData -> TemperatureData -> Bool
$c< :: TemperatureData -> TemperatureData -> Bool
compare :: TemperatureData -> TemperatureData -> Ordering
$ccompare :: TemperatureData -> TemperatureData -> Ordering
$cp1Ord :: Eq TemperatureData
Ord, TemperatureData -> ()
(TemperatureData -> ()) -> NFData TemperatureData
forall a. (a -> ()) -> NFData a
rnf :: TemperatureData -> ()
$crnf :: TemperatureData -> ()
NFData)

instance Resolve TemperatureData where
  type ResolvedValue TemperatureData = TemperatureValue
  resolve :: Context
-> Options
-> TemperatureData
-> Maybe (ResolvedValue TemperatureData, Bool)
resolve Context
_ Options
_ TemperatureData {unit :: TemperatureData -> Maybe TemperatureUnit
unit = Maybe TemperatureUnit
Nothing} = Maybe (ResolvedValue TemperatureData, Bool)
forall a. Maybe a
Nothing
  resolve Context
_ Options
_ TemperatureData {unit :: TemperatureData -> Maybe TemperatureUnit
unit = Just TemperatureUnit
unit, value :: TemperatureData -> Maybe Double
value = Just Double
value} =
    (TemperatureValue, Bool) -> Maybe (TemperatureValue, Bool)
forall a. a -> Maybe a
Just (TemperatureUnit -> Double -> TemperatureValue
simple TemperatureUnit
unit Double
value, Bool
False)
  resolve Context
_ Options
_ TemperatureData {unit :: TemperatureData -> Maybe TemperatureUnit
unit = Just TemperatureUnit
unit, minValue :: TemperatureData -> Maybe Double
minValue = Just Double
from
                              , maxValue :: TemperatureData -> Maybe Double
maxValue = Just Double
to} =
    (TemperatureValue, Bool) -> Maybe (TemperatureValue, Bool)
forall a. a -> Maybe a
Just (TemperatureUnit -> (Double, Double) -> TemperatureValue
between TemperatureUnit
unit (Double
from, Double
to), Bool
False)
  resolve Context
_ Options
_ TemperatureData {unit :: TemperatureData -> Maybe TemperatureUnit
unit = Just TemperatureUnit
unit, minValue :: TemperatureData -> Maybe Double
minValue = Just Double
from} =
    (TemperatureValue, Bool) -> Maybe (TemperatureValue, Bool)
forall a. a -> Maybe a
Just (TemperatureUnit -> Double -> TemperatureValue
above TemperatureUnit
unit Double
from, Bool
False)
  resolve Context
_ Options
_ TemperatureData {unit :: TemperatureData -> Maybe TemperatureUnit
unit = Just TemperatureUnit
unit, maxValue :: TemperatureData -> Maybe Double
maxValue = Just Double
to} =
    (TemperatureValue, Bool) -> Maybe (TemperatureValue, Bool)
forall a. a -> Maybe a
Just (TemperatureUnit -> Double -> TemperatureValue
under TemperatureUnit
unit Double
to, Bool
False)
  resolve Context
_ Options
_ TemperatureData
_ = Maybe (ResolvedValue TemperatureData, Bool)
forall a. Maybe a
Nothing

data IntervalDirection = Above | Under
  deriving (IntervalDirection -> IntervalDirection -> Bool
(IntervalDirection -> IntervalDirection -> Bool)
-> (IntervalDirection -> IntervalDirection -> Bool)
-> Eq IntervalDirection
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: IntervalDirection -> IntervalDirection -> Bool
$c/= :: IntervalDirection -> IntervalDirection -> Bool
== :: IntervalDirection -> IntervalDirection -> Bool
$c== :: IntervalDirection -> IntervalDirection -> Bool
Eq, (forall x. IntervalDirection -> Rep IntervalDirection x)
-> (forall x. Rep IntervalDirection x -> IntervalDirection)
-> Generic IntervalDirection
forall x. Rep IntervalDirection x -> IntervalDirection
forall x. IntervalDirection -> Rep IntervalDirection x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep IntervalDirection x -> IntervalDirection
$cfrom :: forall x. IntervalDirection -> Rep IntervalDirection x
Generic, Int -> IntervalDirection -> Int
IntervalDirection -> Int
(Int -> IntervalDirection -> Int)
-> (IntervalDirection -> Int) -> Hashable IntervalDirection
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: IntervalDirection -> Int
$chash :: IntervalDirection -> Int
hashWithSalt :: Int -> IntervalDirection -> Int
$chashWithSalt :: Int -> IntervalDirection -> Int
Hashable, Eq IntervalDirection
Eq IntervalDirection
-> (IntervalDirection -> IntervalDirection -> Ordering)
-> (IntervalDirection -> IntervalDirection -> Bool)
-> (IntervalDirection -> IntervalDirection -> Bool)
-> (IntervalDirection -> IntervalDirection -> Bool)
-> (IntervalDirection -> IntervalDirection -> Bool)
-> (IntervalDirection -> IntervalDirection -> IntervalDirection)
-> (IntervalDirection -> IntervalDirection -> IntervalDirection)
-> Ord IntervalDirection
IntervalDirection -> IntervalDirection -> Bool
IntervalDirection -> IntervalDirection -> Ordering
IntervalDirection -> IntervalDirection -> IntervalDirection
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: IntervalDirection -> IntervalDirection -> IntervalDirection
$cmin :: IntervalDirection -> IntervalDirection -> IntervalDirection
max :: IntervalDirection -> IntervalDirection -> IntervalDirection
$cmax :: IntervalDirection -> IntervalDirection -> IntervalDirection
>= :: IntervalDirection -> IntervalDirection -> Bool
$c>= :: IntervalDirection -> IntervalDirection -> Bool
> :: IntervalDirection -> IntervalDirection -> Bool
$c> :: IntervalDirection -> IntervalDirection -> Bool
<= :: IntervalDirection -> IntervalDirection -> Bool
$c<= :: IntervalDirection -> IntervalDirection -> Bool
< :: IntervalDirection -> IntervalDirection -> Bool
$c< :: IntervalDirection -> IntervalDirection -> Bool
compare :: IntervalDirection -> IntervalDirection -> Ordering
$ccompare :: IntervalDirection -> IntervalDirection -> Ordering
$cp1Ord :: Eq IntervalDirection
Ord, Int -> IntervalDirection -> ShowS
[IntervalDirection] -> ShowS
IntervalDirection -> String
(Int -> IntervalDirection -> ShowS)
-> (IntervalDirection -> String)
-> ([IntervalDirection] -> ShowS)
-> Show IntervalDirection
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IntervalDirection] -> ShowS
$cshowList :: [IntervalDirection] -> ShowS
show :: IntervalDirection -> String
$cshow :: IntervalDirection -> String
showsPrec :: Int -> IntervalDirection -> ShowS
$cshowsPrec :: Int -> IntervalDirection -> ShowS
Show, IntervalDirection -> ()
(IntervalDirection -> ()) -> NFData IntervalDirection
forall a. (a -> ()) -> NFData a
rnf :: IntervalDirection -> ()
$crnf :: IntervalDirection -> ()
NFData)

data SingleValue = SingleValue
  { SingleValue -> TemperatureUnit
vUnit :: TemperatureUnit
  , SingleValue -> Double
vValue :: Double
  }
  deriving (SingleValue -> SingleValue -> Bool
(SingleValue -> SingleValue -> Bool)
-> (SingleValue -> SingleValue -> Bool) -> Eq SingleValue
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SingleValue -> SingleValue -> Bool
$c/= :: SingleValue -> SingleValue -> Bool
== :: SingleValue -> SingleValue -> Bool
$c== :: SingleValue -> SingleValue -> Bool
Eq, Int -> SingleValue -> ShowS
[SingleValue] -> ShowS
SingleValue -> String
(Int -> SingleValue -> ShowS)
-> (SingleValue -> String)
-> ([SingleValue] -> ShowS)
-> Show SingleValue
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SingleValue] -> ShowS
$cshowList :: [SingleValue] -> ShowS
show :: SingleValue -> String
$cshow :: SingleValue -> String
showsPrec :: Int -> SingleValue -> ShowS
$cshowsPrec :: Int -> SingleValue -> ShowS
Show)

instance ToJSON SingleValue where
  toJSON :: SingleValue -> Value
toJSON (SingleValue TemperatureUnit
unit Double
value) = [Pair] -> Value
object
    [ Text
"value" Text -> Double -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Double
value
    , Text
"unit"  Text -> TemperatureUnit -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= TemperatureUnit
unit
    ]

data TemperatureValue
  = SimpleValue SingleValue
  | IntervalValue (SingleValue, SingleValue)
  | OpenIntervalValue (SingleValue, IntervalDirection)
  deriving (Int -> TemperatureValue -> ShowS
[TemperatureValue] -> ShowS
TemperatureValue -> String
(Int -> TemperatureValue -> ShowS)
-> (TemperatureValue -> String)
-> ([TemperatureValue] -> ShowS)
-> Show TemperatureValue
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TemperatureValue] -> ShowS
$cshowList :: [TemperatureValue] -> ShowS
show :: TemperatureValue -> String
$cshow :: TemperatureValue -> String
showsPrec :: Int -> TemperatureValue -> ShowS
$cshowsPrec :: Int -> TemperatureValue -> ShowS
Show, TemperatureValue -> TemperatureValue -> Bool
(TemperatureValue -> TemperatureValue -> Bool)
-> (TemperatureValue -> TemperatureValue -> Bool)
-> Eq TemperatureValue
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TemperatureValue -> TemperatureValue -> Bool
$c/= :: TemperatureValue -> TemperatureValue -> Bool
== :: TemperatureValue -> TemperatureValue -> Bool
$c== :: TemperatureValue -> TemperatureValue -> Bool
Eq)

instance ToJSON TemperatureValue where
  toJSON :: TemperatureValue -> Value
toJSON (SimpleValue SingleValue
value) = case SingleValue -> Value
forall a. ToJSON a => a -> Value
toJSON SingleValue
value of
    Object Object
o -> Object -> Value
Object (Object -> Value) -> Object -> Value
forall a b. (a -> b) -> a -> b
$ Text -> Value -> Object -> Object
forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
H.insert Text
"type" (Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Text
"value" :: Text)) Object
o
    Value
_        -> Object -> Value
Object Object
forall k v. HashMap k v
H.empty
  toJSON (IntervalValue (SingleValue
from, SingleValue
to)) = [Pair] -> Value
object
    [ Text
"type" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Text
"interval" :: Text)
    , Text
"from" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= SingleValue -> Value
forall a. ToJSON a => a -> Value
toJSON SingleValue
from
    , Text
"to"   Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= SingleValue -> Value
forall a. ToJSON a => a -> Value
toJSON SingleValue
to
    ]
  toJSON (OpenIntervalValue (SingleValue
from, IntervalDirection
Above)) = [Pair] -> Value
object
    [ Text
"type" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Text
"interval" :: Text)
    , Text
"from" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= SingleValue -> Value
forall a. ToJSON a => a -> Value
toJSON SingleValue
from
    ]
  toJSON (OpenIntervalValue (SingleValue
to, IntervalDirection
Under)) = [Pair] -> Value
object
    [ Text
"type" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Text
"interval" :: Text)
    , Text
"to"   Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= SingleValue -> Value
forall a. ToJSON a => a -> Value
toJSON SingleValue
to
    ]

-- -----------------------------------------------------------------
-- Value helpers

simple :: TemperatureUnit -> Double -> TemperatureValue
simple :: TemperatureUnit -> Double -> TemperatureValue
simple TemperatureUnit
u Double
v = SingleValue -> TemperatureValue
SimpleValue (SingleValue -> TemperatureValue)
-> SingleValue -> TemperatureValue
forall a b. (a -> b) -> a -> b
$ TemperatureUnit -> Double -> SingleValue
single TemperatureUnit
u Double
v

between :: TemperatureUnit -> (Double, Double) -> TemperatureValue
between :: TemperatureUnit -> (Double, Double) -> TemperatureValue
between TemperatureUnit
u (Double
from, Double
to) = (SingleValue, SingleValue) -> TemperatureValue
IntervalValue (TemperatureUnit -> Double -> SingleValue
single TemperatureUnit
u Double
from, TemperatureUnit -> Double -> SingleValue
single TemperatureUnit
u Double
to)

above :: TemperatureUnit -> Double -> TemperatureValue
above :: TemperatureUnit -> Double -> TemperatureValue
above = IntervalDirection -> TemperatureUnit -> Double -> TemperatureValue
openInterval IntervalDirection
Above

under :: TemperatureUnit -> Double -> TemperatureValue
under :: TemperatureUnit -> Double -> TemperatureValue
under = IntervalDirection -> TemperatureUnit -> Double -> TemperatureValue
openInterval IntervalDirection
Under

openInterval :: IntervalDirection -> TemperatureUnit -> Double -> TemperatureValue
openInterval :: IntervalDirection -> TemperatureUnit -> Double -> TemperatureValue
openInterval IntervalDirection
direction TemperatureUnit
u Double
v = (SingleValue, IntervalDirection) -> TemperatureValue
OpenIntervalValue (TemperatureUnit -> Double -> SingleValue
single TemperatureUnit
u Double
v, IntervalDirection
direction)

single :: TemperatureUnit -> Double -> SingleValue
single :: TemperatureUnit -> Double -> SingleValue
single TemperatureUnit
u Double
v = SingleValue :: TemperatureUnit -> Double -> SingleValue
SingleValue {vUnit :: TemperatureUnit
vUnit = TemperatureUnit
u, vValue :: Double
vValue = Double
v}

unitsAreCompatible :: Maybe TemperatureUnit -> TemperatureUnit -> Bool
unitsAreCompatible :: Maybe TemperatureUnit -> TemperatureUnit -> Bool
unitsAreCompatible (Just TemperatureUnit
u1) TemperatureUnit
u2 = TemperatureUnit
u1 TemperatureUnit -> TemperatureUnit -> Bool
forall a. Eq a => a -> a -> Bool
== TemperatureUnit
u2
unitsAreCompatible Maybe TemperatureUnit
Nothing TemperatureUnit
_ = Bool
True