-- 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.Distance.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 Unit
  = Centimetre
  | Foot
  | Inch
  | Kilometre
  | M -- ambiguous between Mile and Metre
  | Metre
  | Mile
  | Millimetre
  | Yard
  deriving (Unit -> Unit -> Bool
(Unit -> Unit -> Bool) -> (Unit -> Unit -> Bool) -> Eq Unit
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Unit -> Unit -> Bool
$c/= :: Unit -> Unit -> Bool
== :: Unit -> Unit -> Bool
$c== :: Unit -> Unit -> Bool
Eq, (forall x. Unit -> Rep Unit x)
-> (forall x. Rep Unit x -> Unit) -> Generic Unit
forall x. Rep Unit x -> Unit
forall x. Unit -> Rep Unit x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Unit x -> Unit
$cfrom :: forall x. Unit -> Rep Unit x
Generic, Int -> Unit -> Int
Unit -> Int
(Int -> Unit -> Int) -> (Unit -> Int) -> Hashable Unit
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Unit -> Int
$chash :: Unit -> Int
hashWithSalt :: Int -> Unit -> Int
$chashWithSalt :: Int -> Unit -> Int
Hashable, Eq Unit
Eq Unit
-> (Unit -> Unit -> Ordering)
-> (Unit -> Unit -> Bool)
-> (Unit -> Unit -> Bool)
-> (Unit -> Unit -> Bool)
-> (Unit -> Unit -> Bool)
-> (Unit -> Unit -> Unit)
-> (Unit -> Unit -> Unit)
-> Ord Unit
Unit -> Unit -> Bool
Unit -> Unit -> Ordering
Unit -> Unit -> Unit
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 :: Unit -> Unit -> Unit
$cmin :: Unit -> Unit -> Unit
max :: Unit -> Unit -> Unit
$cmax :: Unit -> Unit -> Unit
>= :: Unit -> Unit -> Bool
$c>= :: Unit -> Unit -> Bool
> :: Unit -> Unit -> Bool
$c> :: Unit -> Unit -> Bool
<= :: Unit -> Unit -> Bool
$c<= :: Unit -> Unit -> Bool
< :: Unit -> Unit -> Bool
$c< :: Unit -> Unit -> Bool
compare :: Unit -> Unit -> Ordering
$ccompare :: Unit -> Unit -> Ordering
$cp1Ord :: Eq Unit
Ord, Int -> Unit -> ShowS
[Unit] -> ShowS
Unit -> String
(Int -> Unit -> ShowS)
-> (Unit -> String) -> ([Unit] -> ShowS) -> Show Unit
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Unit] -> ShowS
$cshowList :: [Unit] -> ShowS
show :: Unit -> String
$cshow :: Unit -> String
showsPrec :: Int -> Unit -> ShowS
$cshowsPrec :: Int -> Unit -> ShowS
Show, Unit -> ()
(Unit -> ()) -> NFData Unit
forall a. (a -> ()) -> NFData a
rnf :: Unit -> ()
$crnf :: Unit -> ()
NFData)

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

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

instance Resolve DistanceData where
  type ResolvedValue DistanceData = DistanceValue
  resolve :: Context
-> Options
-> DistanceData
-> Maybe (ResolvedValue DistanceData, Bool)
resolve Context
_ Options
_ DistanceData {unit :: DistanceData -> Maybe Unit
unit = Just Unit
unit, value :: DistanceData -> Maybe Double
value = Just Double
val} =
    (DistanceValue, Bool) -> Maybe (DistanceValue, Bool)
forall a. a -> Maybe a
Just (Unit -> Double -> DistanceValue
simple Unit
unit Double
val, Bool
False)
  resolve Context
_ Options
_ DistanceData {unit :: DistanceData -> Maybe Unit
unit = Just Unit
unit, value :: DistanceData -> Maybe Double
value = Maybe Double
Nothing
                         , minValue :: DistanceData -> Maybe Double
minValue = Just Double
from, maxValue :: DistanceData -> Maybe Double
maxValue = Just Double
to} =
    (DistanceValue, Bool) -> Maybe (DistanceValue, Bool)
forall a. a -> Maybe a
Just (Unit -> (Double, Double) -> DistanceValue
between Unit
unit (Double
from, Double
to), Bool
False)
  resolve Context
_ Options
_ DistanceData {unit :: DistanceData -> Maybe Unit
unit = Just Unit
unit, value :: DistanceData -> Maybe Double
value = Maybe Double
Nothing
                         , minValue :: DistanceData -> Maybe Double
minValue = Just Double
from, maxValue :: DistanceData -> Maybe Double
maxValue = Maybe Double
Nothing} =
    (DistanceValue, Bool) -> Maybe (DistanceValue, Bool)
forall a. a -> Maybe a
Just (Unit -> Double -> DistanceValue
above Unit
unit Double
from, Bool
False)
  resolve Context
_ Options
_ DistanceData {unit :: DistanceData -> Maybe Unit
unit = Just Unit
unit, value :: DistanceData -> Maybe Double
value = Maybe Double
Nothing
                         , minValue :: DistanceData -> Maybe Double
minValue = Maybe Double
Nothing, maxValue :: DistanceData -> Maybe Double
maxValue = Just Double
to} =
    (DistanceValue, Bool) -> Maybe (DistanceValue, Bool)
forall a. a -> Maybe a
Just (Unit -> Double -> DistanceValue
under Unit
unit Double
to, Bool
False)
  resolve Context
_ Options
_ DistanceData
_ = Maybe (ResolvedValue DistanceData, 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 -> Unit
vUnit :: Unit
  , 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, Eq SingleValue
Eq SingleValue
-> (SingleValue -> SingleValue -> Ordering)
-> (SingleValue -> SingleValue -> Bool)
-> (SingleValue -> SingleValue -> Bool)
-> (SingleValue -> SingleValue -> Bool)
-> (SingleValue -> SingleValue -> Bool)
-> (SingleValue -> SingleValue -> SingleValue)
-> (SingleValue -> SingleValue -> SingleValue)
-> Ord SingleValue
SingleValue -> SingleValue -> Bool
SingleValue -> SingleValue -> Ordering
SingleValue -> SingleValue -> SingleValue
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 :: SingleValue -> SingleValue -> SingleValue
$cmin :: SingleValue -> SingleValue -> SingleValue
max :: SingleValue -> SingleValue -> SingleValue
$cmax :: SingleValue -> SingleValue -> SingleValue
>= :: SingleValue -> SingleValue -> Bool
$c>= :: SingleValue -> SingleValue -> Bool
> :: SingleValue -> SingleValue -> Bool
$c> :: SingleValue -> SingleValue -> Bool
<= :: SingleValue -> SingleValue -> Bool
$c<= :: SingleValue -> SingleValue -> Bool
< :: SingleValue -> SingleValue -> Bool
$c< :: SingleValue -> SingleValue -> Bool
compare :: SingleValue -> SingleValue -> Ordering
$ccompare :: SingleValue -> SingleValue -> Ordering
$cp1Ord :: Eq SingleValue
Ord, 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 Unit
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 -> Unit -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Unit
unit
    ]

data DistanceValue
  = SimpleValue SingleValue
  | IntervalValue (SingleValue, SingleValue)
  | OpenIntervalValue (SingleValue, IntervalDirection)
  deriving (DistanceValue -> DistanceValue -> Bool
(DistanceValue -> DistanceValue -> Bool)
-> (DistanceValue -> DistanceValue -> Bool) -> Eq DistanceValue
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DistanceValue -> DistanceValue -> Bool
$c/= :: DistanceValue -> DistanceValue -> Bool
== :: DistanceValue -> DistanceValue -> Bool
$c== :: DistanceValue -> DistanceValue -> Bool
Eq, Eq DistanceValue
Eq DistanceValue
-> (DistanceValue -> DistanceValue -> Ordering)
-> (DistanceValue -> DistanceValue -> Bool)
-> (DistanceValue -> DistanceValue -> Bool)
-> (DistanceValue -> DistanceValue -> Bool)
-> (DistanceValue -> DistanceValue -> Bool)
-> (DistanceValue -> DistanceValue -> DistanceValue)
-> (DistanceValue -> DistanceValue -> DistanceValue)
-> Ord DistanceValue
DistanceValue -> DistanceValue -> Bool
DistanceValue -> DistanceValue -> Ordering
DistanceValue -> DistanceValue -> DistanceValue
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 :: DistanceValue -> DistanceValue -> DistanceValue
$cmin :: DistanceValue -> DistanceValue -> DistanceValue
max :: DistanceValue -> DistanceValue -> DistanceValue
$cmax :: DistanceValue -> DistanceValue -> DistanceValue
>= :: DistanceValue -> DistanceValue -> Bool
$c>= :: DistanceValue -> DistanceValue -> Bool
> :: DistanceValue -> DistanceValue -> Bool
$c> :: DistanceValue -> DistanceValue -> Bool
<= :: DistanceValue -> DistanceValue -> Bool
$c<= :: DistanceValue -> DistanceValue -> Bool
< :: DistanceValue -> DistanceValue -> Bool
$c< :: DistanceValue -> DistanceValue -> Bool
compare :: DistanceValue -> DistanceValue -> Ordering
$ccompare :: DistanceValue -> DistanceValue -> Ordering
$cp1Ord :: Eq DistanceValue
Ord, Int -> DistanceValue -> ShowS
[DistanceValue] -> ShowS
DistanceValue -> String
(Int -> DistanceValue -> ShowS)
-> (DistanceValue -> String)
-> ([DistanceValue] -> ShowS)
-> Show DistanceValue
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DistanceValue] -> ShowS
$cshowList :: [DistanceValue] -> ShowS
show :: DistanceValue -> String
$cshow :: DistanceValue -> String
showsPrec :: Int -> DistanceValue -> ShowS
$cshowsPrec :: Int -> DistanceValue -> ShowS
Show)

instance ToJSON DistanceValue where
  toJSON :: DistanceValue -> 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 :: Unit -> Double -> DistanceValue
simple :: Unit -> Double -> DistanceValue
simple Unit
u Double
v = SingleValue -> DistanceValue
SimpleValue (SingleValue -> DistanceValue) -> SingleValue -> DistanceValue
forall a b. (a -> b) -> a -> b
$ Unit -> Double -> SingleValue
single Unit
u Double
v

between :: Unit -> (Double, Double) -> DistanceValue
between :: Unit -> (Double, Double) -> DistanceValue
between Unit
u (Double
from, Double
to) = (SingleValue, SingleValue) -> DistanceValue
IntervalValue (Unit -> Double -> SingleValue
single Unit
u Double
from, Unit -> Double -> SingleValue
single Unit
u Double
to)

above :: Unit -> Double -> DistanceValue
above :: Unit -> Double -> DistanceValue
above = IntervalDirection -> Unit -> Double -> DistanceValue
openInterval IntervalDirection
Above

under :: Unit -> Double -> DistanceValue
under :: Unit -> Double -> DistanceValue
under = IntervalDirection -> Unit -> Double -> DistanceValue
openInterval IntervalDirection
Under

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

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