lue-bird / elm-morph / Decimal.Morph

Morph for an arbitrary-sized Decimal

value : Value.Morph.Internal.MorphValue Decimal

MorphValue from a Decimal

To get a MorphValue from a Float, use Float.Morph.decimalOrException over Decimal.Morph.orExceptionValue

row

chars : MorphRow Decimal Char

MorphRow from chars to a Decimal number.

import Morph
import List.Morph

-- trailing 0s are matched but have no effect
"12.0340000"
    |> Morph.toNarrow
        (Decimal.Morph.chars
            |> Morph.rowFinish
            |> Morph.over List.Morph.string
        )
--→ Ok with a Decimal representing
--→ 12.034

"-12.000"
    |> Morph.toNarrow
        (Decimal.Morph.chars
            |> Morph.rowFinish
            |> Morph.over List.Morph.string
        )
--→ Ok with a Decimal representing
--→ -12.0


-- leading floating point is allowed

".012"
    |> Morph.toNarrow
        (Decimal.Morph.chars
            |> Morph.rowFinish
            |> Morph.over List.Morph.string
        )
--→ Ok with a Decimal representing
--→ 0.012

"-.12"
    |> Morph.toNarrow
        (Decimal.Morph.chars
            |> Morph.rowFinish
            |> Morph.over List.Morph.string
        )
--→ Ok with a Decimal representing
--→ -0.12

-- fails for integers without a floating point, see the not below
"12"
    |> Morph.toNarrow
        (Decimal.Morph.chars
            |> Morph.rowFinish
            |> Morph.over List.Morph.string
        )
    |> Result.toMaybe
--> Nothing

-- but succeeds for integers with a trailing floating point
"12."
    |> Morph.toNarrow
        (Decimal.Morph.chars
            |> Morph.rowFinish
            |> Morph.over List.Morph.string
        )
--→ Ok with a Decimal representing
--→ 12.0

-- exponential notation, other letters, symbols etc make it fail

"."
    |> Morph.toNarrow
        (Decimal.Morph.chars
            |> Morph.rowFinish
            |> Morph.over List.Morph.string
        )
    |> Result.toMaybe
--> Nothing

"3e10"
    |> Morph.toNarrow
        (Decimal.Morph.chars
            |> Morph.rowFinish
            |> Morph.over List.Morph.string
        )
    |> Result.toMaybe
--> Nothing

To allow integers to parse as decimals as well, build a Morph.choice between Decimal.Morph.chars and Integer.Morph.chars

The fact that "12." parses as 12 might also seem weird to you. If you don't want to allow that, you'll need to spin your own version, taking this implementation as a reference. It's not that scary I swear!

bitsVariableCount : MorphRow Decimal Bit

MorphRow from from Bits to a Decimal

Decimal or Exception

Morph a Decimal where infinities and NaN are possible states

orExceptionValue : Value.Morph.Internal.MorphValue (Result Decimal.Exception Decimal)

Float MorphValue

exceptionValue : Value.Morph.Internal.MorphValue Decimal.Exception

MorphValue from an Exception

Float

orExceptionFloat : MorphOrError (Result Decimal.Exception Decimal) Basics.Float error_

Morph an elm/core Float to a Result Exception Decimal

Keep in mind that DecimalOrException -> Float can be lossy since Float is fixed in bit size while Decimal is not.

Inverse of Float.Morph.decimalOrException

If you need a narrow Decimal, not a result, try

Result.Morph.toOk
    |> Morph.over Decimal.Morph.orExceptionFloat
    |> Morph.errorMap (Morph.deadEndMap Decimal.exceptionToString)