{-# LANGUAGE OverloadedStrings #-}
module Draw.Plotting.GCode (
GCode(..)
, renderGCode
) where
import Data.List
import Data.Maybe
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Builder as TL
import Formatting hiding (center)
data GCode
= TL.Text
| GBlock [GCode]
| F_Feedrate Double
| M0_Pause
| G00_LinearRapidMove (Maybe Double) (Maybe Double) (Maybe Double)
| G01_LinearFeedrateMove (Maybe Double) (Maybe Double) (Maybe Double) (Maybe Double)
| G02_ArcClockwise (Maybe Double) Double Double Double Double
| G03_ArcCounterClockwise (Maybe Double) Double Double Double Double
| G04_Dwell_ms Double
| G17_Plane_XY
| G18_Plane_ZX
| G19_Plane_YZ
| G20_UseInches
| G21_UseMm
| G28_GotoPredefinedPosition (Maybe Double) (Maybe Double) (Maybe Double)
| G30_GotoPredefinedPosition (Maybe Double) (Maybe Double) (Maybe Double)
| G90_AbsoluteMovement
| G91_RelativeMovement
| G93_Feedrate_TravelInFractionOfMinute
| G94_Feedrate_UnitsPerMinute
deriving (GCode -> GCode -> Bool
(GCode -> GCode -> Bool) -> (GCode -> GCode -> Bool) -> Eq GCode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: GCode -> GCode -> Bool
== :: GCode -> GCode -> Bool
$c/= :: GCode -> GCode -> Bool
/= :: GCode -> GCode -> Bool
Eq, Eq GCode
Eq GCode
-> (GCode -> GCode -> Ordering)
-> (GCode -> GCode -> Bool)
-> (GCode -> GCode -> Bool)
-> (GCode -> GCode -> Bool)
-> (GCode -> GCode -> Bool)
-> (GCode -> GCode -> GCode)
-> (GCode -> GCode -> GCode)
-> Ord GCode
GCode -> GCode -> Bool
GCode -> GCode -> Ordering
GCode -> GCode -> GCode
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 :: GCode -> GCode -> Ordering
compare :: GCode -> GCode -> Ordering
$c< :: GCode -> GCode -> Bool
< :: GCode -> GCode -> Bool
$c<= :: GCode -> GCode -> Bool
<= :: GCode -> GCode -> Bool
$c> :: GCode -> GCode -> Bool
> :: GCode -> GCode -> Bool
$c>= :: GCode -> GCode -> Bool
>= :: GCode -> GCode -> Bool
$cmax :: GCode -> GCode -> GCode
max :: GCode -> GCode -> GCode
$cmin :: GCode -> GCode -> GCode
min :: GCode -> GCode -> GCode
Ord, Int -> GCode -> ShowS
[GCode] -> ShowS
GCode -> String
(Int -> GCode -> ShowS)
-> (GCode -> String) -> ([GCode] -> ShowS) -> Show GCode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> GCode -> ShowS
showsPrec :: Int -> GCode -> ShowS
$cshow :: GCode -> String
show :: GCode -> String
$cshowList :: [GCode] -> ShowS
showList :: [GCode] -> ShowS
Show)
renderGCode :: [GCode] -> TL.Text
renderGCode :: [GCode] -> Text
renderGCode [GBlock [GCode]
xs] = [GCode] -> Text
renderGCode [GCode]
xs
renderGCode [GCode]
xs = Builder -> Text
TL.toLazyText ([Builder] -> Builder
forall a. Monoid a => [a] -> a
mconcat (Builder -> [Builder] -> [Builder]
forall a. a -> [a] -> [a]
intersperse Builder
"\n" ((GCode -> Builder) -> [GCode] -> [Builder]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> GCode -> Builder
renderGcodeIndented Int
0) [GCode]
xs)))
renderGcodeIndented :: Int -> GCode -> TL.Builder
renderGcodeIndented :: Int -> GCode -> Builder
renderGcodeIndented !Int
level = \case
GComment Text
comment -> Builder -> Builder
indent (Builder
"; " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Text -> Builder
TL.fromLazyText Text
comment)
GBlock [GCode]
content -> [Builder] -> Builder
forall a. Monoid a => [a] -> a
mconcat (Builder -> [Builder] -> [Builder]
forall a. a -> [a] -> [a]
intersperse Builder
"\n" ((GCode -> Builder) -> [GCode] -> [Builder]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> GCode -> Builder
renderGcodeIndented (Int
levelInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)) [GCode]
content))
F_Feedrate Double
f -> Builder -> Builder
indent (Format Builder (Double -> Builder) -> Double -> Builder
forall a. Format Builder a -> a
bformat (Format (Double -> Builder) (Double -> Builder)
"F " Format (Double -> Builder) (Double -> Builder)
-> Format Builder (Double -> Builder)
-> Format Builder (Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Format Builder (Double -> Builder)
forall r. Format r (Double -> r)
double) Double
f)
GCode
M0_Pause -> Builder -> Builder
indent Builder
"M0 (Pause/wait for user input)"
G00_LinearRapidMove Maybe Double
x Maybe Double
y Maybe Double
z
| (Maybe Double -> Bool) -> [Maybe Double] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Maybe Double -> Bool
forall a. Maybe a -> Bool
isNothing [Maybe Double
x,Maybe Double
y,Maybe Double
z] -> Text -> Builder
errorComment Text
"G0 requires at least one coordinate argument; omitting empty G0"
| Bool
otherwise -> Builder -> Builder
indent (Format
Builder (Maybe Double -> Maybe Double -> Maybe Double -> Builder)
-> Maybe Double -> Maybe Double -> Maybe Double -> Builder
forall a. Format Builder a -> a
bformat (Format
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
"G0" Format
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
-> Format
Builder (Maybe Double -> Maybe Double -> Maybe Double -> Builder)
-> Format
Builder (Maybe Double -> Maybe Double -> Maybe Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder
-> Format
(Maybe Double -> Maybe Double -> Builder)
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
forall r. Builder -> Format r (Maybe Double -> r)
optional Builder
"X" Format
(Maybe Double -> Maybe Double -> Builder)
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
-> Format Builder (Maybe Double -> Maybe Double -> Builder)
-> Format
Builder (Maybe Double -> Maybe Double -> Maybe Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder
-> Format
(Maybe Double -> Builder) (Maybe Double -> Maybe Double -> Builder)
forall r. Builder -> Format r (Maybe Double -> r)
optional Builder
"Y" Format
(Maybe Double -> Builder) (Maybe Double -> Maybe Double -> Builder)
-> Format Builder (Maybe Double -> Builder)
-> Format Builder (Maybe Double -> Maybe Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder -> Format Builder (Maybe Double -> Builder)
forall r. Builder -> Format r (Maybe Double -> r)
optional Builder
"Z") Maybe Double
x Maybe Double
y Maybe Double
z)
G01_LinearFeedrateMove Maybe Double
f Maybe Double
x Maybe Double
y Maybe Double
z
| (Maybe Double -> Bool) -> [Maybe Double] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Maybe Double -> Bool
forall a. Maybe a -> Bool
isNothing [Maybe Double
x,Maybe Double
y,Maybe Double
z] -> Text -> Builder
errorComment Text
"G1 requires at least one coordinate argument; omitting empty G1"
| Bool
otherwise -> Builder -> Builder
indent (Format
Builder
(Maybe Double
-> Maybe Double -> Maybe Double -> Maybe Double -> Builder)
-> Maybe Double
-> Maybe Double
-> Maybe Double
-> Maybe Double
-> Builder
forall a. Format Builder a -> a
bformat (Format
(Maybe Double
-> Maybe Double -> Maybe Double -> Maybe Double -> Builder)
(Maybe Double
-> Maybe Double -> Maybe Double -> Maybe Double -> Builder)
"G1" Format
(Maybe Double
-> Maybe Double -> Maybe Double -> Maybe Double -> Builder)
(Maybe Double
-> Maybe Double -> Maybe Double -> Maybe Double -> Builder)
-> Format
Builder
(Maybe Double
-> Maybe Double -> Maybe Double -> Maybe Double -> Builder)
-> Format
Builder
(Maybe Double
-> Maybe Double -> Maybe Double -> Maybe Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder
-> Format
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
(Maybe Double
-> Maybe Double -> Maybe Double -> Maybe Double -> Builder)
forall r. Builder -> Format r (Maybe Double -> r)
optional Builder
"F" Format
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
(Maybe Double
-> Maybe Double -> Maybe Double -> Maybe Double -> Builder)
-> Format
Builder (Maybe Double -> Maybe Double -> Maybe Double -> Builder)
-> Format
Builder
(Maybe Double
-> Maybe Double -> Maybe Double -> Maybe Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder
-> Format
(Maybe Double -> Maybe Double -> Builder)
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
forall r. Builder -> Format r (Maybe Double -> r)
optional Builder
"X" Format
(Maybe Double -> Maybe Double -> Builder)
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
-> Format Builder (Maybe Double -> Maybe Double -> Builder)
-> Format
Builder (Maybe Double -> Maybe Double -> Maybe Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder
-> Format
(Maybe Double -> Builder) (Maybe Double -> Maybe Double -> Builder)
forall r. Builder -> Format r (Maybe Double -> r)
optional Builder
"Y" Format
(Maybe Double -> Builder) (Maybe Double -> Maybe Double -> Builder)
-> Format Builder (Maybe Double -> Builder)
-> Format Builder (Maybe Double -> Maybe Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder -> Format Builder (Maybe Double -> Builder)
forall r. Builder -> Format r (Maybe Double -> r)
optional Builder
"Z") Maybe Double
f Maybe Double
x Maybe Double
y Maybe Double
z)
G02_ArcClockwise Maybe Double
f Double
i Double
j Double
x Double
y -> Builder -> Builder
indent (Format
Builder
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
-> Maybe Double -> Double -> Double -> Double -> Double -> Builder
forall a. Format Builder a -> a
bformat (Format
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
"G2" Format
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
-> Format
Builder
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
-> Format
Builder
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder
-> Format
(Double -> Double -> Double -> Double -> Builder)
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
forall r. Builder -> Format r (Maybe Double -> r)
optional Builder
"F" Format
(Double -> Double -> Double -> Double -> Builder)
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
-> Format Builder (Double -> Double -> Double -> Double -> Builder)
-> Format
Builder
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder
-> Format
(Double -> Double -> Double -> Builder)
(Double -> Double -> Double -> Double -> Builder)
forall r. Builder -> Format r (Double -> r)
required Builder
"X" Format
(Double -> Double -> Double -> Builder)
(Double -> Double -> Double -> Double -> Builder)
-> Format Builder (Double -> Double -> Double -> Builder)
-> Format Builder (Double -> Double -> Double -> Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder
-> Format
(Double -> Double -> Builder)
(Double -> Double -> Double -> Builder)
forall r. Builder -> Format r (Double -> r)
required Builder
"Y" Format
(Double -> Double -> Builder)
(Double -> Double -> Double -> Builder)
-> Format Builder (Double -> Double -> Builder)
-> Format Builder (Double -> Double -> Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder -> Format (Double -> Builder) (Double -> Double -> Builder)
forall r. Builder -> Format r (Double -> r)
required Builder
"I" Format (Double -> Builder) (Double -> Double -> Builder)
-> Format Builder (Double -> Builder)
-> Format Builder (Double -> Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder -> Format Builder (Double -> Builder)
forall r. Builder -> Format r (Double -> r)
required Builder
"J") Maybe Double
f Double
x Double
y Double
i Double
j)
G03_ArcCounterClockwise Maybe Double
f Double
i Double
j Double
x Double
y -> Builder -> Builder
indent (Format
Builder
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
-> Maybe Double -> Double -> Double -> Double -> Double -> Builder
forall a. Format Builder a -> a
bformat (Format
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
"G3" Format
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
-> Format
Builder
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
-> Format
Builder
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder
-> Format
(Double -> Double -> Double -> Double -> Builder)
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
forall r. Builder -> Format r (Maybe Double -> r)
optional Builder
"F" Format
(Double -> Double -> Double -> Double -> Builder)
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
-> Format Builder (Double -> Double -> Double -> Double -> Builder)
-> Format
Builder
(Maybe Double -> Double -> Double -> Double -> Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder
-> Format
(Double -> Double -> Double -> Builder)
(Double -> Double -> Double -> Double -> Builder)
forall r. Builder -> Format r (Double -> r)
required Builder
"X" Format
(Double -> Double -> Double -> Builder)
(Double -> Double -> Double -> Double -> Builder)
-> Format Builder (Double -> Double -> Double -> Builder)
-> Format Builder (Double -> Double -> Double -> Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder
-> Format
(Double -> Double -> Builder)
(Double -> Double -> Double -> Builder)
forall r. Builder -> Format r (Double -> r)
required Builder
"Y" Format
(Double -> Double -> Builder)
(Double -> Double -> Double -> Builder)
-> Format Builder (Double -> Double -> Builder)
-> Format Builder (Double -> Double -> Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder -> Format (Double -> Builder) (Double -> Double -> Builder)
forall r. Builder -> Format r (Double -> r)
required Builder
"I" Format (Double -> Builder) (Double -> Double -> Builder)
-> Format Builder (Double -> Builder)
-> Format Builder (Double -> Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder -> Format Builder (Double -> Builder)
forall r. Builder -> Format r (Double -> r)
required Builder
"J") Maybe Double
f Double
x Double
y Double
i Double
j)
G04_Dwell_ms Double
s -> Builder -> Builder
indent (Format Builder (Double -> Builder) -> Double -> Builder
forall a. Format Builder a -> a
bformat (Format (Double -> Builder) (Double -> Builder)
"G4" Format (Double -> Builder) (Double -> Builder)
-> Format Builder (Double -> Builder)
-> Format Builder (Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder -> Format Builder (Double -> Builder)
forall r. Builder -> Format r (Double -> r)
required Builder
"P") Double
s)
GCode
G17_Plane_XY -> Builder -> Builder
indent Builder
"G17 (Use XY plane)"
GCode
G18_Plane_ZX -> Builder -> Builder
indent Builder
"G18 (Use ZX plane)"
GCode
G19_Plane_YZ -> Builder -> Builder
indent Builder
"G19 (Use YZ plane)"
GCode
G20_UseInches -> String -> Builder
forall a. HasCallStack => String -> a
error String
"Inches aren’t going to happen here, sorry."
GCode
G21_UseMm -> Builder -> Builder
indent Builder
"G21 (Use mm)"
G28_GotoPredefinedPosition Maybe Double
x Maybe Double
y Maybe Double
z -> Builder -> Builder
indent (Format
Builder (Maybe Double -> Maybe Double -> Maybe Double -> Builder)
-> Maybe Double -> Maybe Double -> Maybe Double -> Builder
forall a. Format Builder a -> a
bformat (Format
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
"G28" Format
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
-> Format
Builder (Maybe Double -> Maybe Double -> Maybe Double -> Builder)
-> Format
Builder (Maybe Double -> Maybe Double -> Maybe Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder
-> Format
(Maybe Double -> Maybe Double -> Builder)
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
forall r. Builder -> Format r (Maybe Double -> r)
optional Builder
"X" Format
(Maybe Double -> Maybe Double -> Builder)
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
-> Format Builder (Maybe Double -> Maybe Double -> Builder)
-> Format
Builder (Maybe Double -> Maybe Double -> Maybe Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder
-> Format
(Maybe Double -> Builder) (Maybe Double -> Maybe Double -> Builder)
forall r. Builder -> Format r (Maybe Double -> r)
optional Builder
"Y" Format
(Maybe Double -> Builder) (Maybe Double -> Maybe Double -> Builder)
-> Format Builder (Maybe Double -> Builder)
-> Format Builder (Maybe Double -> Maybe Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder -> Format Builder (Maybe Double -> Builder)
forall r. Builder -> Format r (Maybe Double -> r)
optional Builder
"Z") Maybe Double
x Maybe Double
y Maybe Double
z)
G30_GotoPredefinedPosition Maybe Double
x Maybe Double
y Maybe Double
z -> Builder -> Builder
indent (Format
Builder (Maybe Double -> Maybe Double -> Maybe Double -> Builder)
-> Maybe Double -> Maybe Double -> Maybe Double -> Builder
forall a. Format Builder a -> a
bformat (Format
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
"G30" Format
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
-> Format
Builder (Maybe Double -> Maybe Double -> Maybe Double -> Builder)
-> Format
Builder (Maybe Double -> Maybe Double -> Maybe Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder
-> Format
(Maybe Double -> Maybe Double -> Builder)
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
forall r. Builder -> Format r (Maybe Double -> r)
optional Builder
"X" Format
(Maybe Double -> Maybe Double -> Builder)
(Maybe Double -> Maybe Double -> Maybe Double -> Builder)
-> Format Builder (Maybe Double -> Maybe Double -> Builder)
-> Format
Builder (Maybe Double -> Maybe Double -> Maybe Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder
-> Format
(Maybe Double -> Builder) (Maybe Double -> Maybe Double -> Builder)
forall r. Builder -> Format r (Maybe Double -> r)
optional Builder
"Y" Format
(Maybe Double -> Builder) (Maybe Double -> Maybe Double -> Builder)
-> Format Builder (Maybe Double -> Builder)
-> Format Builder (Maybe Double -> Maybe Double -> Builder)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder -> Format Builder (Maybe Double -> Builder)
forall r. Builder -> Format r (Maybe Double -> r)
optional Builder
"Z") Maybe Double
x Maybe Double
y Maybe Double
z)
GCode
G90_AbsoluteMovement -> Builder -> Builder
indent Builder
"G90 ;(G9(0) => abs(0)lute movement)"
GCode
G91_RelativeMovement -> Builder -> Builder
indent Builder
"G91 ;(G9(1) => re(1)ative movement)"
GCode
G93_Feedrate_TravelInFractionOfMinute -> Builder -> Builder
indent Builder
"G93 (feedrate is time to travel in fractions of one minute: F1000 = make the move in 60/1000 min)"
GCode
G94_Feedrate_UnitsPerMinute -> Builder -> Builder
indent Builder
"G94 (feedrate is units per minute: F1000 = move at 1000 mm/min)"
where
indentation :: Text
indentation = Text
" "
indent :: Builder -> Builder
indent Builder
x = Text -> Builder
TL.fromLazyText (Int64 -> Text -> Text
TL.replicate (Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
level) Text
indentation) Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
x
errorComment :: Text -> Builder
errorComment Text
msg = Int -> GCode -> Builder
renderGcodeIndented Int
level (Text -> GCode
GComment (Text
"ERROR: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
msg))
required :: TL.Builder -> Format r (Double -> r)
required :: forall r. Builder -> Format r (Double -> r)
required Builder
x = Format (Double -> r) (Double -> r)
" " Format (Double -> r) (Double -> r)
-> Format r (Double -> r) -> Format r (Double -> r)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Builder -> Format (Double -> r) (Double -> r)
forall r. Builder -> Format r r
now Builder
x Format (Double -> r) (Double -> r)
-> Format r (Double -> r) -> Format r (Double -> r)
forall r a r'. Format r a -> Format r' r -> Format r' a
% Format r (Double -> r)
forall r. Format r (Double -> r)
double
optional :: TL.Builder -> Format r (Maybe Double -> r)
optional :: forall r. Builder -> Format r (Maybe Double -> r)
optional = Format Builder (Double -> Builder) -> Format r (Maybe Double -> r)
forall a r.
Format Builder (a -> Builder) -> Format r (Maybe a -> r)
optioned (Format Builder (Double -> Builder)
-> Format r (Maybe Double -> r))
-> (Builder -> Format Builder (Double -> Builder))
-> Builder
-> Format r (Maybe Double -> r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Format Builder (Double -> Builder)
forall r. Builder -> Format r (Double -> r)
required
double :: Format r (Double -> r)
double :: forall r. Format r (Double -> r)
double = let decimals :: Int
decimals = Int
3 in Int -> Format r (Double -> r)
forall a r. Real a => Int -> Format r (a -> r)
fixed Int
decimals