{-# LANGUAGE
    OverloadedStrings
  , GeneralizedNewtypeDeriving
  , FlexibleInstances
  , ExistentialQuantification
  , StandaloneDeriving
  , TypeFamilies
  , EmptyDataDecls
  #-}
module Clay.Size
(

-- * Size type.
  Size
, LengthUnit
, Percentage
, nil
, unitless

-- * Size constructors.

, cm
, mm
, inches
, px
, pt
, pc
, em
, ex
, ch
, pct
, rem
, lh
, rlh
, vw
, vh
, vmin
, vmax
, vb
, vi
, svw
, svh
, lvw
, lvh
, dvw
, dvh
, fr
, maxContent
, minContent
, available
, fitContent

-- * Calculation operators for calc

, (@+@)
, (@-@)
, (@*)
, (*@)
, (@/)

-- * Shorthands for properties that can be applied separately to each box side.

, sym
, sym2
, sym3

-- * Angle type.

, Angle
, Deg
, Rad
, Grad
, Turn

-- * Constructing angles.

, deg
, rad
, grad
, turn

)
where

import Data.Monoid
import Prelude hiding (rem)
import Data.Text (Text)

import Clay.Common
import Clay.Property
import Clay.Stylesheet

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

-- | Sizes can be given using a length unit (e.g. em, px).
data LengthUnit

-- | Sizes can be given in percentages.
data Percentage

-- | When combining percentages with units using calc, we get a combination
data Combination

data Size a =
  SimpleSize Text |
  forall b c. SumSize (Size b) (Size c) |
  forall b c. DiffSize (Size b) (Size c) |
  MultSize Number (Size a) |
  DivSize Number (Size a) |
  OtherSize Value

deriving instance Show (Size a)

sizeToText :: Size a -> Text
sizeToText :: forall a. Size a -> Text
sizeToText (SimpleSize Text
txt) = Text
txt
sizeToText (SumSize Size b
a Size c
b) = [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat [Text
"(", Size b -> Text
forall a. Size a -> Text
sizeToText Size b
a, Text
" + ", Size c -> Text
forall a. Size a -> Text
sizeToText Size c
b, Text
")"]
sizeToText (DiffSize Size b
a Size c
b) = [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat [Text
"(", Size b -> Text
forall a. Size a -> Text
sizeToText Size b
a, Text
" - ", Size c -> Text
forall a. Size a -> Text
sizeToText Size c
b, Text
")"]
sizeToText (MultSize Number
a Size a
b) = [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat [Text
"(", Number -> Text
cssNumberText Number
a, Text
" * ", Size a -> Text
forall a. Size a -> Text
sizeToText Size a
b, Text
")"]
sizeToText (DivSize Number
a Size a
b) = [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat [Text
"(", Size a -> Text
forall a. Size a -> Text
sizeToText Size a
b, Text
" / ", Number -> Text
cssNumberText Number
a, Text
")"]
sizeToText (OtherSize Value
a) = Prefixed -> Text
plain (Prefixed -> Text) -> Prefixed -> Text
forall a b. (a -> b) -> a -> b
$ Value -> Prefixed
unValue Value
a

instance Val (Size a) where
  value :: Size a -> Value
value (SimpleSize Text
a) = Text -> Value
forall a. Val a => a -> Value
value Text
a
  value (OtherSize Value
a) = Value
a
  value Size a
s = Prefixed -> Value
Value (Prefixed -> Value) -> Prefixed -> Value
forall a b. (a -> b) -> a -> b
$ Prefixed
browsers Prefixed -> Prefixed -> Prefixed
forall a. Semigroup a => a -> a -> a
<> Text -> Prefixed
Plain (Text
"calc" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Size a -> Text
forall a. Size a -> Text
sizeToText Size a
s)

instance Auto (Size a) where auto :: Size a
auto = Value -> Size a
forall a. Value -> Size a
OtherSize Value
Clay.Common.autoValue
instance Normal (Size a) where normal :: Size a
normal = Value -> Size a
forall a. Value -> Size a
OtherSize Value
Clay.Common.normalValue
instance Inherit (Size a) where inherit :: Size a
inherit = Value -> Size a
forall a. Value -> Size a
OtherSize Value
Clay.Common.inheritValue
instance None (Size a) where none :: Size a
none = Value -> Size a
forall a. Value -> Size a
OtherSize Value
Clay.Common.noneValue
instance Other (Size a) where other :: Value -> Size a
other Value
a = Value -> Size a
forall a. Value -> Size a
OtherSize Value
a

-- | Zero size.
nil :: Size a
nil :: forall a. Size a
nil = Text -> Size a
forall a. Text -> Size a
SimpleSize Text
"0"

-- | Unitless size (as recommended for line-height).
unitless :: Number -> Size a
unitless :: forall a. Number -> Size a
unitless Number
i = Text -> Size a
forall a. Text -> Size a
SimpleSize ((Prefixed -> Text
plain (Prefixed -> Text) -> (Number -> Prefixed) -> Number -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Prefixed
unValue (Value -> Prefixed) -> (Number -> Value) -> Number -> Prefixed
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Number -> Value
forall a. Val a => a -> Value
value) Number
i)

cm, mm, inches, px, pt, pc :: Number -> Size LengthUnit

-- | Size in centimeters.
cm :: Number -> Size LengthUnit
cm Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"cm")

-- | Size in millimeters.
mm :: Number -> Size LengthUnit
mm Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"mm")

-- | Size in inches (1in = 2.54 cm).
inches :: Number -> Size LengthUnit
inches Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"in")

-- | Size in pixels.
px :: Number -> Size LengthUnit
px Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"px")

-- | Size in points (1pt = 1/72 of 1in).
pt :: Number -> Size LengthUnit
pt Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"pt")

-- | Size in picas (1pc = 12pt).
pc :: Number -> Size LengthUnit
pc Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"pc")

em, ex, ch, rem, lh, rlh, vw, vh, vmin, vmax, vb, vi, svw, svh, lvw, lvh, dvw, dvh, fr :: Number -> Size LengthUnit

-- | Size in em's (computed cssNumberText of the font-size).
em :: Number -> Size LengthUnit
em Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"em")

-- | SimpleSize in ex'es (x-height of the first avaliable font).
ex :: Number -> Size LengthUnit
ex Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"ex")

-- | SimpleSize in ch's (The width of the glyph "0" of the element's font).
ch :: Number -> Size LengthUnit
ch Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"ch")

-- | SimpleSize in rem's (em's, but always relative to the root element).
rem :: Number -> Size LengthUnit
rem Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"rem")

-- | SimpleSize in lh's (Line height of the element).
lh :: Number -> Size LengthUnit
lh Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"lh")

-- | SimpleSize in rlh's (lh's, but always relative to the root element).
rlh :: Number -> Size LengthUnit
rlh Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"rlh")

-- | SimpleSize in vw's (1vw = 1% of viewport width).
vw :: Number -> Size LengthUnit
vw Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"vw")

-- | SimpleSize in vh's (1vh = 1% of viewport height).
vh :: Number -> Size LengthUnit
vh Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"vh")

-- | SimpleSize in vmin's (the smaller of vw or vh).
vmin :: Number -> Size LengthUnit
vmin Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"vmin")

-- | SimpleSize in vmax's (the larger of vw or vh).
vmax :: Number -> Size LengthUnit
vmax Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"vmax")

-- | SimpleSize in vb's (1vb = 1% of the parent's size in the direction of the root element's block axis).
vb :: Number -> Size LengthUnit
vb Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"vb")

-- | SimpleSize in vi's (1vi = 1% of the parent's size in the direction of the root element's inline axis).
vi :: Number -> Size LengthUnit
vi Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"vi")

-- | SimpleSize in svw's (1svw = 1% of the small viewport's width).
svw :: Number -> Size LengthUnit
svw Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"svw")

-- | SimpleSize in svh's (1svh = 1% of the small viewport's height).
svh :: Number -> Size LengthUnit
svh Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"svh")

-- | SimpleSize in lvw's (1lvw = 1% of the large viewport's width).
lvw :: Number -> Size LengthUnit
lvw Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"lvw")

-- | SimpleSize in lvh's (1lvh = 1% of the large viewport's height).
lvh :: Number -> Size LengthUnit
lvh Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"lvh")

-- | SimpleSize in dvw's (1dvw = 1% of the dynamic viewport's width).
dvw :: Number -> Size LengthUnit
dvw Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"dvw")

-- | SimpleSize in dvh's (1dvh = 1% of the dynamic viewport's height).
dvh :: Number -> Size LengthUnit
dvh Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"dvh")

-- | 'SimpleSize' in fr's (a fractional unit and 1fr is for 1 part of the available space in grid areas).
fr :: Number -> Size LengthUnit
fr Number
i = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"fr")

-- | SimpleSize for the intrinsic preferred width.
maxContent :: Size LengthUnit
maxContent :: Size LengthUnit
maxContent = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize Text
"max-content"

-- | SimpleSize for the intrinsic minimum width.
minContent :: Size LengthUnit
minContent :: Size LengthUnit
minContent = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize Text
"min-content"

-- | SimpleSize for the containing block width minus horizontal margin, border, and padding.
available :: Size LengthUnit
available :: Size LengthUnit
available = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize Text
"available"

-- | The larger of the intrinsic minimum width or the smaller of the intrinsic preferred width and the available width.
fitContent :: Size LengthUnit
fitContent :: Size LengthUnit
fitContent = Text -> Size LengthUnit
forall a. Text -> Size a
SimpleSize Text
"fit-content"

-- | SimpleSize in percents.
pct :: Number -> Size Percentage
pct :: Number -> Size Percentage
pct Number
i = Text -> Size Percentage
forall a. Text -> Size a
SimpleSize (Number -> Text
cssNumberText Number
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"%")

instance Num (Size LengthUnit) where
  fromInteger :: Integer -> Size LengthUnit
fromInteger = Number -> Size LengthUnit
px (Number -> Size LengthUnit)
-> (Integer -> Number) -> Integer -> Size LengthUnit
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Number
forall a. Num a => Integer -> a
fromInteger
  + :: Size LengthUnit -> Size LengthUnit -> Size LengthUnit
(+)    = String -> Size LengthUnit -> Size LengthUnit -> Size LengthUnit
forall a. HasCallStack => String -> a
error   String
"plus not implemented for Size"
  * :: Size LengthUnit -> Size LengthUnit -> Size LengthUnit
(*)    = String -> Size LengthUnit -> Size LengthUnit -> Size LengthUnit
forall a. HasCallStack => String -> a
error  String
"times not implemented for Size"
  abs :: Size LengthUnit -> Size LengthUnit
abs    = String -> Size LengthUnit -> Size LengthUnit
forall a. HasCallStack => String -> a
error    String
"abs not implemented for Size"
  signum :: Size LengthUnit -> Size LengthUnit
signum = String -> Size LengthUnit -> Size LengthUnit
forall a. HasCallStack => String -> a
error String
"signum not implemented for Size"
  negate :: Size LengthUnit -> Size LengthUnit
negate = String -> Size LengthUnit -> Size LengthUnit
forall a. HasCallStack => String -> a
error String
"negate not implemented for Size"

instance Fractional (Size LengthUnit) where
  fromRational :: Rational -> Size LengthUnit
fromRational = Number -> Size LengthUnit
px (Number -> Size LengthUnit)
-> (Rational -> Number) -> Rational -> Size LengthUnit
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Number
forall a. Fractional a => Rational -> a
fromRational
  recip :: Size LengthUnit -> Size LengthUnit
recip  = String -> Size LengthUnit -> Size LengthUnit
forall a. HasCallStack => String -> a
error  String
"recip not implemented for Size"

instance Num (Size Percentage) where
  fromInteger :: Integer -> Size Percentage
fromInteger = Number -> Size Percentage
pct (Number -> Size Percentage)
-> (Integer -> Number) -> Integer -> Size Percentage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Number
forall a. Num a => Integer -> a
fromInteger
  + :: Size Percentage -> Size Percentage -> Size Percentage
(+)    = String -> Size Percentage -> Size Percentage -> Size Percentage
forall a. HasCallStack => String -> a
error   String
"plus not implemented for Size"
  * :: Size Percentage -> Size Percentage -> Size Percentage
(*)    = String -> Size Percentage -> Size Percentage -> Size Percentage
forall a. HasCallStack => String -> a
error  String
"times not implemented for Size"
  abs :: Size Percentage -> Size Percentage
abs    = String -> Size Percentage -> Size Percentage
forall a. HasCallStack => String -> a
error    String
"abs not implemented for Size"
  signum :: Size Percentage -> Size Percentage
signum = String -> Size Percentage -> Size Percentage
forall a. HasCallStack => String -> a
error String
"signum not implemented for Size"
  negate :: Size Percentage -> Size Percentage
negate = String -> Size Percentage -> Size Percentage
forall a. HasCallStack => String -> a
error String
"negate not implemented for Size"

instance Fractional (Size Percentage) where
  fromRational :: Rational -> Size Percentage
fromRational = Number -> Size Percentage
pct (Number -> Size Percentage)
-> (Rational -> Number) -> Rational -> Size Percentage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Number
forall a. Fractional a => Rational -> a
fromRational
  recip :: Size Percentage -> Size Percentage
recip  = String -> Size Percentage -> Size Percentage
forall a. HasCallStack => String -> a
error  String
"recip not implemented for Size"

-- | Type family to define what is the result of a calc operation

type family SizeCombination sa sb where
  SizeCombination Percentage Percentage = Percentage
  SizeCombination LengthUnit LengthUnit = LengthUnit
  SizeCombination a b = Combination

-- | Plus operator to combine sizes into calc function
infixl 6 @+@
(@+@) :: Size a -> Size b -> Size (SizeCombination a b)
Size a
a @+@ :: forall a b. Size a -> Size b -> Size (SizeCombination a b)
@+@ Size b
b = Size a -> Size b -> Size (SizeCombination a b)
forall a b c. Size b -> Size c -> Size a
SumSize Size a
a Size b
b

-- | Minus operator to combine sizes into calc function
infixl 6 @-@
(@-@) :: Size a -> Size b -> Size (SizeCombination a b)
Size a
a @-@ :: forall a b. Size a -> Size b -> Size (SizeCombination a b)
@-@ Size b
b = Size a -> Size b -> Size (SizeCombination a b)
forall a b c. Size b -> Size c -> Size a
DiffSize Size a
a Size b
b

-- | Times operator to combine sizes into calc function
infixl 7 *@
(*@) :: Number -> Size a -> Size a
Number
a *@ :: forall a. Number -> Size a -> Size a
*@ Size a
b = Number -> Size a -> Size a
forall a. Number -> Size a -> Size a
MultSize Number
a Size a
b

-- | Reversed times operator to combine sizes into calc function
infixl 7 @*
(@*) :: Size a -> Number -> Size a
Size a
a @* :: forall a. Size a -> Number -> Size a
@* Number
b = Number -> Size a -> Size a
forall a. Number -> Size a -> Size a
MultSize Number
b Size a
a

-- | Division operator to combine sizes into calc function
infixl 7 @/
(@/) :: Size a -> Number -> Size a
Size a
a @/ :: forall a. Size a -> Number -> Size a
@/ Number
b = Number -> Size a -> Size a
forall a. Number -> Size a -> Size a
DivSize Number
b Size a
a

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

sym :: (a -> a -> a -> a -> Css) -> a -> Css
sym :: forall a. (a -> a -> a -> a -> Css) -> a -> Css
sym a -> a -> a -> a -> Css
k a
a = a -> a -> a -> a -> Css
k a
a a
a a
a a
a

sym3 :: (tb -> l -> tb -> r -> Css) -> tb -> l -> r -> Css
sym3 :: forall tb l r. (tb -> l -> tb -> r -> Css) -> tb -> l -> r -> Css
sym3 tb -> l -> tb -> r -> Css
k tb
tb l
l r
r = tb -> l -> tb -> r -> Css
k tb
tb l
l tb
tb r
r

sym2 :: (tb -> lr -> tb -> lr -> Css) -> tb -> lr -> Css
sym2 :: forall tb lr. (tb -> lr -> tb -> lr -> Css) -> tb -> lr -> Css
sym2 tb -> lr -> tb -> lr -> Css
k tb
tb lr
lr = tb -> lr -> tb -> lr -> Css
k tb
tb lr
lr tb
tb lr
lr

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

data Deg
data Rad
data Grad
data Turn

newtype Angle a = Angle Value
  deriving (Angle a -> Value
(Angle a -> Value) -> Val (Angle a)
forall a. Angle a -> Value
forall a. (a -> Value) -> Val a
$cvalue :: forall a. Angle a -> Value
value :: Angle a -> Value
Val, Angle a
Angle a -> Auto (Angle a)
forall a. Angle a
forall a. a -> Auto a
$cauto :: forall a. Angle a
auto :: Angle a
Auto, Angle a
Angle a -> Inherit (Angle a)
forall a. Angle a
forall a. a -> Inherit a
$cinherit :: forall a. Angle a
inherit :: Angle a
Inherit, Value -> Angle a
(Value -> Angle a) -> Other (Angle a)
forall a. Value -> Angle a
forall a. (Value -> a) -> Other a
$cother :: forall a. Value -> Angle a
other :: Value -> Angle a
Other)

-- | Angle in degrees.
deg :: Number -> Angle Deg
deg :: Number -> Angle Deg
deg Number
i = Value -> Angle Deg
forall a. Value -> Angle a
Angle (Number -> Value
forall a. Val a => a -> Value
value Number
i Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
"deg")

-- | Angle in radians.
rad :: Number -> Angle Rad
rad :: Number -> Angle Rad
rad Number
i = Value -> Angle Rad
forall a. Value -> Angle a
Angle (Number -> Value
forall a. Val a => a -> Value
value Number
i Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
"rad")

-- | Angle in gradians (also knows as gons or grades).
grad :: Number -> Angle Grad
grad :: Number -> Angle Grad
grad Number
i = Value -> Angle Grad
forall a. Value -> Angle a
Angle (Number -> Value
forall a. Val a => a -> Value
value Number
i Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
"grad")

-- | Angle in turns.
turn :: Number -> Angle Turn
turn :: Number -> Angle Turn
turn Number
i = Value -> Angle Turn
forall a. Value -> Angle a
Angle (Number -> Value
forall a. Val a => a -> Value
value Number
i Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
"turn")

instance Num (Angle Deg) where
  fromInteger :: Integer -> Angle Deg
fromInteger = Number -> Angle Deg
deg (Number -> Angle Deg)
-> (Integer -> Number) -> Integer -> Angle Deg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Number
forall a. Num a => Integer -> a
fromInteger
  + :: Angle Deg -> Angle Deg -> Angle Deg
(+)    = String -> Angle Deg -> Angle Deg -> Angle Deg
forall a. HasCallStack => String -> a
error   String
"plus not implemented for Angle"
  * :: Angle Deg -> Angle Deg -> Angle Deg
(*)    = String -> Angle Deg -> Angle Deg -> Angle Deg
forall a. HasCallStack => String -> a
error  String
"times not implemented for Angle"
  abs :: Angle Deg -> Angle Deg
abs    = String -> Angle Deg -> Angle Deg
forall a. HasCallStack => String -> a
error    String
"abs not implemented for Angle"
  signum :: Angle Deg -> Angle Deg
signum = String -> Angle Deg -> Angle Deg
forall a. HasCallStack => String -> a
error String
"signum not implemented for Angle"
  negate :: Angle Deg -> Angle Deg
negate = String -> Angle Deg -> Angle Deg
forall a. HasCallStack => String -> a
error String
"negate not implemented for Angle"

instance Fractional (Angle Deg) where
  fromRational :: Rational -> Angle Deg
fromRational = Number -> Angle Deg
deg (Number -> Angle Deg)
-> (Rational -> Number) -> Rational -> Angle Deg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Number
forall a. Fractional a => Rational -> a
fromRational
  recip :: Angle Deg -> Angle Deg
recip  = String -> Angle Deg -> Angle Deg
forall a. HasCallStack => String -> a
error  String
"recip not implemented for Angle"

instance Num (Angle Rad) where
  fromInteger :: Integer -> Angle Rad
fromInteger = Number -> Angle Rad
rad (Number -> Angle Rad)
-> (Integer -> Number) -> Integer -> Angle Rad
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Number
forall a. Num a => Integer -> a
fromInteger
  + :: Angle Rad -> Angle Rad -> Angle Rad
(+)    = String -> Angle Rad -> Angle Rad -> Angle Rad
forall a. HasCallStack => String -> a
error   String
"plus not implemented for Angle"
  * :: Angle Rad -> Angle Rad -> Angle Rad
(*)    = String -> Angle Rad -> Angle Rad -> Angle Rad
forall a. HasCallStack => String -> a
error  String
"times not implemented for Angle"
  abs :: Angle Rad -> Angle Rad
abs    = String -> Angle Rad -> Angle Rad
forall a. HasCallStack => String -> a
error    String
"abs not implemented for Angle"
  signum :: Angle Rad -> Angle Rad
signum = String -> Angle Rad -> Angle Rad
forall a. HasCallStack => String -> a
error String
"signum not implemented for Angle"
  negate :: Angle Rad -> Angle Rad
negate = String -> Angle Rad -> Angle Rad
forall a. HasCallStack => String -> a
error String
"negate not implemented for Angle"

instance Fractional (Angle Rad) where
  fromRational :: Rational -> Angle Rad
fromRational = Number -> Angle Rad
rad (Number -> Angle Rad)
-> (Rational -> Number) -> Rational -> Angle Rad
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Number
forall a. Fractional a => Rational -> a
fromRational
  recip :: Angle Rad -> Angle Rad
recip  = String -> Angle Rad -> Angle Rad
forall a. HasCallStack => String -> a
error  String
"recip not implemented for Angle"

instance Num (Angle Grad) where
  fromInteger :: Integer -> Angle Grad
fromInteger = Number -> Angle Grad
grad (Number -> Angle Grad)
-> (Integer -> Number) -> Integer -> Angle Grad
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Number
forall a. Num a => Integer -> a
fromInteger
  + :: Angle Grad -> Angle Grad -> Angle Grad
(+)    = String -> Angle Grad -> Angle Grad -> Angle Grad
forall a. HasCallStack => String -> a
error   String
"plus not implemented for Angle"
  * :: Angle Grad -> Angle Grad -> Angle Grad
(*)    = String -> Angle Grad -> Angle Grad -> Angle Grad
forall a. HasCallStack => String -> a
error  String
"times not implemented for Angle"
  abs :: Angle Grad -> Angle Grad
abs    = String -> Angle Grad -> Angle Grad
forall a. HasCallStack => String -> a
error    String
"abs not implemented for Angle"
  signum :: Angle Grad -> Angle Grad
signum = String -> Angle Grad -> Angle Grad
forall a. HasCallStack => String -> a
error String
"signum not implemented for Angle"
  negate :: Angle Grad -> Angle Grad
negate = String -> Angle Grad -> Angle Grad
forall a. HasCallStack => String -> a
error String
"negate not implemented for Angle"

instance Fractional (Angle Grad) where
  fromRational :: Rational -> Angle Grad
fromRational = Number -> Angle Grad
grad (Number -> Angle Grad)
-> (Rational -> Number) -> Rational -> Angle Grad
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Number
forall a. Fractional a => Rational -> a
fromRational
  recip :: Angle Grad -> Angle Grad
recip  = String -> Angle Grad -> Angle Grad
forall a. HasCallStack => String -> a
error  String
"recip not implemented for Angle"

instance Num (Angle Turn) where
  fromInteger :: Integer -> Angle Turn
fromInteger = Number -> Angle Turn
turn (Number -> Angle Turn)
-> (Integer -> Number) -> Integer -> Angle Turn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Number
forall a. Num a => Integer -> a
fromInteger
  + :: Angle Turn -> Angle Turn -> Angle Turn
(+)    = String -> Angle Turn -> Angle Turn -> Angle Turn
forall a. HasCallStack => String -> a
error   String
"plus not implemented for Angle"
  * :: Angle Turn -> Angle Turn -> Angle Turn
(*)    = String -> Angle Turn -> Angle Turn -> Angle Turn
forall a. HasCallStack => String -> a
error  String
"times not implemented for Angle"
  abs :: Angle Turn -> Angle Turn
abs    = String -> Angle Turn -> Angle Turn
forall a. HasCallStack => String -> a
error    String
"abs not implemented for Angle"
  signum :: Angle Turn -> Angle Turn
signum = String -> Angle Turn -> Angle Turn
forall a. HasCallStack => String -> a
error String
"signum not implemented for Angle"
  negate :: Angle Turn -> Angle Turn
negate = String -> Angle Turn -> Angle Turn
forall a. HasCallStack => String -> a
error String
"negate not implemented for Angle"

instance Fractional (Angle Turn) where
  fromRational :: Rational -> Angle Turn
fromRational = Number -> Angle Turn
turn (Number -> Angle Turn)
-> (Rational -> Number) -> Rational -> Angle Turn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Number
forall a. Fractional a => Rational -> a
fromRational
  recip :: Angle Turn -> Angle Turn
recip  = String -> Angle Turn -> Angle Turn
forall a. HasCallStack => String -> a
error  String
"recip not implemented for Angle"