git.iko.soy/purescript-literals
on main help sign in
Add Number.Literal
0d67fe1Tomasz Rybarczyk
spago.dhall+3
@@ -8,8 +8,11 @@ You can edit this file as you like.
8 [ "assert"
8 [ "assert"
9 , "effect"
9 , "effect"
10 , "console"
10 , "console"
11+ , "numbers"
12+ , "partial"
11 , "psci-support"
13 , "psci-support"
12 , "unsafe-coerce"
14 , "unsafe-coerce"
15+ , "typelevel-prelude"
13 ]
16 ]
14, packages =
17, packages =
15 ./packages.dhall
18 ./packages.dhall
src/Literals/Number.pursnew file+52
@@ -0,0 +1,52 @@
1+module Literals.Number where
2+
3+import Data.Maybe (fromJust)
4+import Data.Number (fromString)
5+import Data.Symbol (class IsSymbol, SProxy(..))
6+import Partial.Unsafe (unsafePartial)
7+import Prim.Symbol (class Cons)
8+import Type.Prelude (reflectSymbol)
9+import Unsafe.Coerce (unsafeCoerce)
10+
11+class Digit (s :: Symbol)
12+
13+instance digit0 :: Digit "0"
14+else instance digit1 :: Digit "1"
15+else instance digit2 :: Digit "2"
16+else instance digit3 :: Digit "3"
17+else instance digit4 :: Digit "4"
18+else instance digit5 :: Digit "5"
19+else instance digit6 :: Digit "6"
20+else instance digit7 :: Digit "7"
21+else instance digit8 :: Digit "8"
22+else instance digit9 :: Digit "9"
23+
24+class Number (sym :: Symbol)
25+
26+instance numberInstance :: (Number' h t Sign, Cons h t s) => Number s
27+
28+foreign import kind NumberPart
29+foreign import data Sign :: NumberPart
30+foreign import data FirstDigit :: NumberPart
31+foreign import data IntegerPart :: NumberPart
32+foreign import data FractionalPart :: NumberPart
33+
34+class Number' (head :: Symbol) (tail :: Symbol) (part :: NumberPart)
35+
36+instance signPart :: (Cons h' t' t, Number' h' t' FirstDigit) => Number' "-" t Sign
37+else instance signPartEmpty :: (Number' h t FirstDigit) => Number' h t Sign
38+else instance firstDigit :: (Digit h, Number' h t IntegerPart) => Number' h t FirstDigit
39+else instance pointIntegerPart :: (Cons h' t' t, Number' h' t' FractionalPart) => Number' "." t IntegerPart
40+else instance lastIntegerPart :: (Digit h) ⇒ Number' h "" IntegerPart
41+else instance digitIntegerPart :: (Digit h, Cons h' t' t, Number' h' t' IntegerPart) => Number' h t IntegerPart
42+else instance lastFractionalPart :: Number' h "" FractionalPart
43+else instance digitFractionalPart :: (Digit h, Cons h' t' t, Number' h' t' FractionalPart) => Number' h t FractionalPart
44+
45+foreign import data Literal ∷ Symbol → Type
46+
47+literal :: ∀ s. IsSymbol s ⇒ Number s => Literal s
48+literal = (unsafeCoerce (unsafePartial (fromJust (fromString (reflectSymbol (SProxy :: SProxy s))))))
49+
50+toNumber ∷ ∀ s. Literal s → Number
51+toNumber = unsafeCoerce
52+
src/Literal.purs → src/Literals/String.pursrenamed+2−1
@@ -1,4 +1,4 @@
1−module Literal
1+module Literals.String
2 ( Literal
2 ( Literal
3 , literal
3 , literal
4 , toString
4 , toString
@@ -14,3 +14,4 @@ literal = unsafeCoerce (reflectSymbol (SProxy :: SProxy sym))
14
14
15toString :: forall sym. Literal sym -> String
15toString :: forall sym. Literal sym -> String
16toString = unsafeCoerce
16toString = unsafeCoerce
17+
test/Main.purs+26−2
@@ -3,13 +3,37 @@ module Test.Main where
3import Prelude
3import Prelude
4
4
5import Effect (Effect)
5import Effect (Effect)
6+import Literals.Number (Literal, literal) as Number
6−import Literal (Literal, literal)
7+import Literals.String (Literal, literal) as String
7import Test.Assert (assertEqual)
8import Test.Assert (assertEqual)
8import Unsafe.Coerce (unsafeCoerce)
9import Unsafe.Coerce (unsafeCoerce)
9
10
11+
10main :: Effect Unit
12main :: Effect Unit
11main = do
13main = do
12 assertEqual
14 assertEqual
13− { actual: unsafeCoerce (literal :: Literal "foo")
15+ { actual: unsafeCoerce (String.literal :: String.Literal "foo")
14 , expected: "foo"
16 , expected: "foo"
15 }
17 }
18+ assertEqual
19+ { actual: unsafeCoerce (Number.literal :: Number.Literal "8")
20+ , expected: 8.0
21+ }
22+ assertEqual
23+ { actual: unsafeCoerce (Number.literal :: Number.Literal "-8")
24+ , expected: -8.0
25+ }
26+ assertEqual
27+ { actual: unsafeCoerce (Number.literal :: Number.Literal "100.0")
28+ , expected: 100.0
29+ }
30+ assertEqual
31+ { actual: unsafeCoerce (Number.literal :: Number.Literal "-100.0")
32+ , expected: -100.0
33+ }
34+ assertEqual
35+ { actual: unsafeCoerce (Number.literal :: Number.Literal "0.0")
36+ , expected: 0.0
37+ }
38+
39+