{-# LANGUAGE OverloadedStrings, GeneralizedNewtypeDeriving #-}
module Clay.Property where

import Control.Arrow (second)
import Data.Fixed (Fixed, HasResolution (resolution), showFixed)
import Data.List (partition, sort)
import Data.List.NonEmpty (NonEmpty, toList)
import Data.Maybe
import Data.String
import Data.Text (Text, replace)

data Prefixed = Prefixed { Prefixed -> [(Text, Text)]
unPrefixed :: [(Text, Text)] } | Plain { Prefixed -> Text
unPlain :: Text }
  deriving (Int -> Prefixed -> ShowS
[Prefixed] -> ShowS
Prefixed -> String
(Int -> Prefixed -> ShowS)
-> (Prefixed -> String) -> ([Prefixed] -> ShowS) -> Show Prefixed
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Prefixed -> ShowS
showsPrec :: Int -> Prefixed -> ShowS
$cshow :: Prefixed -> String
show :: Prefixed -> String
$cshowList :: [Prefixed] -> ShowS
showList :: [Prefixed] -> ShowS
Show, Prefixed -> Prefixed -> Bool
(Prefixed -> Prefixed -> Bool)
-> (Prefixed -> Prefixed -> Bool) -> Eq Prefixed
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Prefixed -> Prefixed -> Bool
== :: Prefixed -> Prefixed -> Bool
$c/= :: Prefixed -> Prefixed -> Bool
/= :: Prefixed -> Prefixed -> Bool
Eq)

instance IsString Prefixed where
  fromString :: String -> Prefixed
fromString String
s = Text -> Prefixed
Plain (String -> Text
forall a. IsString a => String -> a
fromString String
s)

instance Semigroup Prefixed where
  <> :: Prefixed -> Prefixed -> Prefixed
(<>) = Prefixed -> Prefixed -> Prefixed
merge

instance Monoid Prefixed where
  mempty :: Prefixed
mempty  = Prefixed
""
  mappend :: Prefixed -> Prefixed -> Prefixed
mappend = Prefixed -> Prefixed -> Prefixed
forall a. Semigroup a => a -> a -> a
(<>)

merge :: Prefixed -> Prefixed -> Prefixed
merge :: Prefixed -> Prefixed -> Prefixed
merge (Plain    Text
x ) (Plain    Text
y ) = Text -> Prefixed
Plain (Text
x Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
y)
merge (Plain    Text
x ) (Prefixed [(Text, Text)]
ys) = [(Text, Text)] -> Prefixed
Prefixed (((Text, Text) -> (Text, Text)) -> [(Text, Text)] -> [(Text, Text)]
forall a b. (a -> b) -> [a] -> [b]
map ((Text -> Text) -> (Text, Text) -> (Text, Text)
forall b c d. (b -> c) -> (d, b) -> (d, c)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second (Text
x Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>)) [(Text, Text)]
ys)
merge (Prefixed [(Text, Text)]
xs) (Plain    Text
y ) = [(Text, Text)] -> Prefixed
Prefixed (((Text, Text) -> (Text, Text)) -> [(Text, Text)] -> [(Text, Text)]
forall a b. (a -> b) -> [a] -> [b]
map ((Text -> Text) -> (Text, Text) -> (Text, Text)
forall b c d. (b -> c) -> (d, b) -> (d, c)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second (Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
y)) [(Text, Text)]
xs)
merge (Prefixed [(Text, Text)]
xs) (Prefixed [(Text, Text)]
ys) =
  let kys :: [Text]
kys = ((Text, Text) -> Text) -> [(Text, Text)] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Text, Text) -> Text
forall a b. (a, b) -> a
fst [(Text, Text)]
ys
      kxs :: [Text]
kxs = ((Text, Text) -> Text) -> [(Text, Text)] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Text, Text) -> Text
forall a b. (a, b) -> a
fst [(Text, Text)]
xs
   in [(Text, Text)] -> Prefixed
Prefixed ([(Text, Text)] -> Prefixed) -> [(Text, Text)] -> Prefixed
forall a b. (a -> b) -> a -> b
$ ((Text, Text) -> (Text, Text) -> (Text, Text))
-> [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\(Text
p, Text
a) (Text
_, Text
b) -> (Text
p, Text
a Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
b))
        ([(Text, Text)] -> [(Text, Text)]
forall a. Ord a => [a] -> [a]
sort (([(Text, Text)], [(Text, Text)]) -> [(Text, Text)]
forall a b. (a, b) -> a
fst (((Text, Text) -> Bool)
-> [(Text, Text)] -> ([(Text, Text)], [(Text, Text)])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition ((Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
kys) (Text -> Bool) -> ((Text, Text) -> Text) -> (Text, Text) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text, Text) -> Text
forall a b. (a, b) -> a
fst) [(Text, Text)]
xs)))
        ([(Text, Text)] -> [(Text, Text)]
forall a. Ord a => [a] -> [a]
sort (([(Text, Text)], [(Text, Text)]) -> [(Text, Text)]
forall a b. (a, b) -> a
fst (((Text, Text) -> Bool)
-> [(Text, Text)] -> ([(Text, Text)], [(Text, Text)])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition ((Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
kxs) (Text -> Bool) -> ((Text, Text) -> Text) -> (Text, Text) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text, Text) -> Text
forall a b. (a, b) -> a
fst) [(Text, Text)]
ys)))

plain :: Prefixed -> Text
plain :: Prefixed -> Text
plain (Prefixed [(Text, Text)]
xs) = Text
"" Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
`fromMaybe` Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"" [(Text, Text)]
xs
plain (Plain    Text
p ) = Text
p

quote :: Text -> Text
quote :: Text -> Text
quote Text
t = Text
"\"" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
replace Text
"\"" Text
"\\\"" Text
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\""

-------------------------------------------------------------------------------

newtype Key a = Key { forall a. Key a -> Prefixed
unKeys :: Prefixed }
  deriving (Int -> Key a -> ShowS
[Key a] -> ShowS
Key a -> String
(Int -> Key a -> ShowS)
-> (Key a -> String) -> ([Key a] -> ShowS) -> Show (Key a)
forall a. Int -> Key a -> ShowS
forall a. [Key a] -> ShowS
forall a. Key a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Int -> Key a -> ShowS
showsPrec :: Int -> Key a -> ShowS
$cshow :: forall a. Key a -> String
show :: Key a -> String
$cshowList :: forall a. [Key a] -> ShowS
showList :: [Key a] -> ShowS
Show, NonEmpty (Key a) -> Key a
Key a -> Key a -> Key a
(Key a -> Key a -> Key a)
-> (NonEmpty (Key a) -> Key a)
-> (forall b. Integral b => b -> Key a -> Key a)
-> Semigroup (Key a)
forall b. Integral b => b -> Key a -> Key a
forall a. NonEmpty (Key a) -> Key a
forall a. Key a -> Key a -> Key a
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall a b. Integral b => b -> Key a -> Key a
$c<> :: forall a. Key a -> Key a -> Key a
<> :: Key a -> Key a -> Key a
$csconcat :: forall a. NonEmpty (Key a) -> Key a
sconcat :: NonEmpty (Key a) -> Key a
$cstimes :: forall a b. Integral b => b -> Key a -> Key a
stimes :: forall b. Integral b => b -> Key a -> Key a
Semigroup, Semigroup (Key a)
Key a
Semigroup (Key a) =>
Key a
-> (Key a -> Key a -> Key a)
-> ([Key a] -> Key a)
-> Monoid (Key a)
[Key a] -> Key a
Key a -> Key a -> Key a
forall a. Semigroup (Key a)
forall a. Key a
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall a. [Key a] -> Key a
forall a. Key a -> Key a -> Key a
$cmempty :: forall a. Key a
mempty :: Key a
$cmappend :: forall a. Key a -> Key a -> Key a
mappend :: Key a -> Key a -> Key a
$cmconcat :: forall a. [Key a] -> Key a
mconcat :: [Key a] -> Key a
Monoid, String -> Key a
(String -> Key a) -> IsString (Key a)
forall a. String -> Key a
forall a. (String -> a) -> IsString a
$cfromString :: forall a. String -> Key a
fromString :: String -> Key a
IsString)

cast :: Key a -> Key ()
cast :: forall a. Key a -> Key ()
cast (Key Prefixed
k) = Prefixed -> Key ()
forall a. Prefixed -> Key a
Key Prefixed
k

-------------------------------------------------------------------------------

newtype Value = Value { Value -> Prefixed
unValue :: Prefixed }
  deriving (Int -> Value -> ShowS
[Value] -> ShowS
Value -> String
(Int -> Value -> ShowS)
-> (Value -> String) -> ([Value] -> ShowS) -> Show Value
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Value -> ShowS
showsPrec :: Int -> Value -> ShowS
$cshow :: Value -> String
show :: Value -> String
$cshowList :: [Value] -> ShowS
showList :: [Value] -> ShowS
Show, NonEmpty Value -> Value
Value -> Value -> Value
(Value -> Value -> Value)
-> (NonEmpty Value -> Value)
-> (forall b. Integral b => b -> Value -> Value)
-> Semigroup Value
forall b. Integral b => b -> Value -> Value
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
$c<> :: Value -> Value -> Value
<> :: Value -> Value -> Value
$csconcat :: NonEmpty Value -> Value
sconcat :: NonEmpty Value -> Value
$cstimes :: forall b. Integral b => b -> Value -> Value
stimes :: forall b. Integral b => b -> Value -> Value
Semigroup, Semigroup Value
Value
Semigroup Value =>
Value
-> (Value -> Value -> Value) -> ([Value] -> Value) -> Monoid Value
[Value] -> Value
Value -> Value -> Value
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
$cmempty :: Value
mempty :: Value
$cmappend :: Value -> Value -> Value
mappend :: Value -> Value -> Value
$cmconcat :: [Value] -> Value
mconcat :: [Value] -> Value
Monoid, String -> Value
(String -> Value) -> IsString Value
forall a. (String -> a) -> IsString a
$cfromString :: String -> Value
fromString :: String -> Value
IsString, Value -> Value -> Bool
(Value -> Value -> Bool) -> (Value -> Value -> Bool) -> Eq Value
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Value -> Value -> Bool
== :: Value -> Value -> Bool
$c/= :: Value -> Value -> Bool
/= :: Value -> Value -> Bool
Eq)

class Val a where
  value :: a -> Value

instance Val Text where
  value :: Text -> Value
value Text
t = Prefixed -> Value
Value (Text -> Prefixed
Plain Text
t)

newtype Literal = Literal Text
  deriving (Int -> Literal -> ShowS
[Literal] -> ShowS
Literal -> String
(Int -> Literal -> ShowS)
-> (Literal -> String) -> ([Literal] -> ShowS) -> Show Literal
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Literal -> ShowS
showsPrec :: Int -> Literal -> ShowS
$cshow :: Literal -> String
show :: Literal -> String
$cshowList :: [Literal] -> ShowS
showList :: [Literal] -> ShowS
Show, NonEmpty Literal -> Literal
Literal -> Literal -> Literal
(Literal -> Literal -> Literal)
-> (NonEmpty Literal -> Literal)
-> (forall b. Integral b => b -> Literal -> Literal)
-> Semigroup Literal
forall b. Integral b => b -> Literal -> Literal
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
$c<> :: Literal -> Literal -> Literal
<> :: Literal -> Literal -> Literal
$csconcat :: NonEmpty Literal -> Literal
sconcat :: NonEmpty Literal -> Literal
$cstimes :: forall b. Integral b => b -> Literal -> Literal
stimes :: forall b. Integral b => b -> Literal -> Literal
Semigroup, Semigroup Literal
Literal
Semigroup Literal =>
Literal
-> (Literal -> Literal -> Literal)
-> ([Literal] -> Literal)
-> Monoid Literal
[Literal] -> Literal
Literal -> Literal -> Literal
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
$cmempty :: Literal
mempty :: Literal
$cmappend :: Literal -> Literal -> Literal
mappend :: Literal -> Literal -> Literal
$cmconcat :: [Literal] -> Literal
mconcat :: [Literal] -> Literal
Monoid, String -> Literal
(String -> Literal) -> IsString Literal
forall a. (String -> a) -> IsString a
$cfromString :: String -> Literal
fromString :: String -> Literal
IsString)

instance Val Literal where
  value :: Literal -> Value
value (Literal Text
t) = Prefixed -> Value
Value (Text -> Prefixed
Plain (Text -> Text
quote Text
t))

instance Val Integer where
  value :: Integer -> Value
value = String -> Value
forall a. IsString a => String -> a
fromString (String -> Value) -> (Integer -> String) -> Integer -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> String
forall a. Show a => a -> String
show

data E5 = E5
instance HasResolution E5 where resolution :: forall (p :: * -> *). p E5 -> Integer
resolution p E5
_ = Integer
100000

instance Val Value where
  value :: Value -> Value
value = Value -> Value
forall a. a -> a
id

instance Val a => Val (Maybe a) where
  value :: Maybe a -> Value
value Maybe a
Nothing  = Value
""
  value (Just a
a) = a -> Value
forall a. Val a => a -> Value
value a
a

instance (Val a, Val b) => Val (a, b) where
  value :: (a, b) -> Value
value (a
a, b
b) = a -> Value
forall a. Val a => a -> Value
value a
a Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
" " Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> b -> Value
forall a. Val a => a -> Value
value b
b

instance (Val a, Val b) => Val (Either a b) where
  value :: Either a b -> Value
value (Left  a
a) = a -> Value
forall a. Val a => a -> Value
value a
a
  value (Right b
a) = b -> Value
forall a. Val a => a -> Value
value b
a

instance Val a => Val [a] where
  value :: [a] -> Value
value [a]
xs = Value -> [Value] -> Value
forall a. Monoid a => a -> [a] -> a
intercalate Value
"," ((a -> Value) -> [a] -> [Value]
forall a b. (a -> b) -> [a] -> [b]
map a -> Value
forall a. Val a => a -> Value
value [a]
xs)

instance Val a => Val (NonEmpty a) where
  value :: NonEmpty a -> Value
value = [a] -> Value
forall a. Val a => a -> Value
value ([a] -> Value) -> (NonEmpty a -> [a]) -> NonEmpty a -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty a -> [a]
forall a. NonEmpty a -> [a]
toList

intercalate :: Monoid a => a -> [a] -> a
intercalate :: forall a. Monoid a => a -> [a] -> a
intercalate a
_ []     = a
forall a. Monoid a => a
mempty
intercalate a
s (a
x:[a]
xs) = (a -> a -> a) -> a -> [a] -> a
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\a
a a
b -> a
a a -> a -> a
forall a. Monoid a => a -> a -> a
`mappend` a
s a -> a -> a
forall a. Monoid a => a -> a -> a
`mappend` a
b) a
x [a]
xs

-------------------------------------------------------------------------------

-- | A number type to represent the CSS @number@ type.
--   It has fixed precision, supporting up to 5 decimal places.
newtype Number = Number { Number -> Fixed E5
unNumber :: Fixed E5 }
  deriving (Int -> Number
Number -> Int
Number -> [Number]
Number -> Number
Number -> Number -> [Number]
Number -> Number -> Number -> [Number]
(Number -> Number)
-> (Number -> Number)
-> (Int -> Number)
-> (Number -> Int)
-> (Number -> [Number])
-> (Number -> Number -> [Number])
-> (Number -> Number -> [Number])
-> (Number -> Number -> Number -> [Number])
-> Enum Number
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Number -> Number
succ :: Number -> Number
$cpred :: Number -> Number
pred :: Number -> Number
$ctoEnum :: Int -> Number
toEnum :: Int -> Number
$cfromEnum :: Number -> Int
fromEnum :: Number -> Int
$cenumFrom :: Number -> [Number]
enumFrom :: Number -> [Number]
$cenumFromThen :: Number -> Number -> [Number]
enumFromThen :: Number -> Number -> [Number]
$cenumFromTo :: Number -> Number -> [Number]
enumFromTo :: Number -> Number -> [Number]
$cenumFromThenTo :: Number -> Number -> Number -> [Number]
enumFromThenTo :: Number -> Number -> Number -> [Number]
Enum, Number -> Number -> Bool
(Number -> Number -> Bool)
-> (Number -> Number -> Bool) -> Eq Number
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Number -> Number -> Bool
== :: Number -> Number -> Bool
$c/= :: Number -> Number -> Bool
/= :: Number -> Number -> Bool
Eq, Num Number
Num Number =>
(Number -> Number -> Number)
-> (Number -> Number) -> (Rational -> Number) -> Fractional Number
Rational -> Number
Number -> Number
Number -> Number -> Number
forall a.
Num a =>
(a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
$c/ :: Number -> Number -> Number
/ :: Number -> Number -> Number
$crecip :: Number -> Number
recip :: Number -> Number
$cfromRational :: Rational -> Number
fromRational :: Rational -> Number
Fractional, Integer -> Number
Number -> Number
Number -> Number -> Number
(Number -> Number -> Number)
-> (Number -> Number -> Number)
-> (Number -> Number -> Number)
-> (Number -> Number)
-> (Number -> Number)
-> (Number -> Number)
-> (Integer -> Number)
-> Num Number
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: Number -> Number -> Number
+ :: Number -> Number -> Number
$c- :: Number -> Number -> Number
- :: Number -> Number -> Number
$c* :: Number -> Number -> Number
* :: Number -> Number -> Number
$cnegate :: Number -> Number
negate :: Number -> Number
$cabs :: Number -> Number
abs :: Number -> Number
$csignum :: Number -> Number
signum :: Number -> Number
$cfromInteger :: Integer -> Number
fromInteger :: Integer -> Number
Num, Eq Number
Eq Number =>
(Number -> Number -> Ordering)
-> (Number -> Number -> Bool)
-> (Number -> Number -> Bool)
-> (Number -> Number -> Bool)
-> (Number -> Number -> Bool)
-> (Number -> Number -> Number)
-> (Number -> Number -> Number)
-> Ord Number
Number -> Number -> Bool
Number -> Number -> Ordering
Number -> Number -> Number
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
$ccompare :: Number -> Number -> Ordering
compare :: Number -> Number -> Ordering
$c< :: Number -> Number -> Bool
< :: Number -> Number -> Bool
$c<= :: Number -> Number -> Bool
<= :: Number -> Number -> Bool
$c> :: Number -> Number -> Bool
> :: Number -> Number -> Bool
$c>= :: Number -> Number -> Bool
>= :: Number -> Number -> Bool
$cmax :: Number -> Number -> Number
max :: Number -> Number -> Number
$cmin :: Number -> Number -> Number
min :: Number -> Number -> Number
Ord, ReadPrec [Number]
ReadPrec Number
Int -> ReadS Number
ReadS [Number]
(Int -> ReadS Number)
-> ReadS [Number]
-> ReadPrec Number
-> ReadPrec [Number]
-> Read Number
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Number
readsPrec :: Int -> ReadS Number
$creadList :: ReadS [Number]
readList :: ReadS [Number]
$creadPrec :: ReadPrec Number
readPrec :: ReadPrec Number
$creadListPrec :: ReadPrec [Number]
readListPrec :: ReadPrec [Number]
Read, Num Number
Ord Number
(Num Number, Ord Number) => (Number -> Rational) -> Real Number
Number -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
$ctoRational :: Number -> Rational
toRational :: Number -> Rational
Real, Fractional Number
Real Number
(Real Number, Fractional Number) =>
(forall b. Integral b => Number -> (b, Number))
-> (forall b. Integral b => Number -> b)
-> (forall b. Integral b => Number -> b)
-> (forall b. Integral b => Number -> b)
-> (forall b. Integral b => Number -> b)
-> RealFrac Number
forall b. Integral b => Number -> b
forall b. Integral b => Number -> (b, Number)
forall a.
(Real a, Fractional a) =>
(forall b. Integral b => a -> (b, a))
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> RealFrac a
$cproperFraction :: forall b. Integral b => Number -> (b, Number)
properFraction :: forall b. Integral b => Number -> (b, Number)
$ctruncate :: forall b. Integral b => Number -> b
truncate :: forall b. Integral b => Number -> b
$cround :: forall b. Integral b => Number -> b
round :: forall b. Integral b => Number -> b
$cceiling :: forall b. Integral b => Number -> b
ceiling :: forall b. Integral b => Number -> b
$cfloor :: forall b. Integral b => Number -> b
floor :: forall b. Integral b => Number -> b
RealFrac, Int -> Number -> ShowS
[Number] -> ShowS
Number -> String
(Int -> Number -> ShowS)
-> (Number -> String) -> ([Number] -> ShowS) -> Show Number
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Number -> ShowS
showsPrec :: Int -> Number -> ShowS
$cshow :: Number -> String
show :: Number -> String
$cshowList :: [Number] -> ShowS
showList :: [Number] -> ShowS
Show)

instance Val Number where
  value :: Number -> Value
value = Prefixed -> Value
Value (Prefixed -> Value) -> (Number -> Prefixed) -> Number -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Prefixed
Plain (Text -> Prefixed) -> (Number -> Text) -> Number -> Prefixed
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Number -> Text
cssNumberText

cssNumberText :: Number -> Text
cssNumberText :: Number -> Text
cssNumberText = String -> Text
forall a. IsString a => String -> a
fromString (String -> Text) -> (Number -> String) -> Number -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Fixed E5 -> String
forall {k} (a :: k). HasResolution a => Bool -> Fixed a -> String
showFixed Bool
True (Fixed E5 -> String) -> (Number -> Fixed E5) -> Number -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Number -> Fixed E5
unNumber

-------------------------------------------------------------------------------

noCommas :: Val a => [a] -> Value
noCommas :: forall a. Val a => [a] -> Value
noCommas [a]
xs = Value -> [Value] -> Value
forall a. Monoid a => a -> [a] -> a
intercalate Value
" " ((a -> Value) -> [a] -> [Value]
forall a b. (a -> b) -> [a] -> [b]
map a -> Value
forall a. Val a => a -> Value
value [a]
xs)

infixr !

(!) :: a -> b -> (a, b)
! :: forall a b. a -> b -> (a, b)
(!) = (,)