git.iko.soy/purescript-literals
on main help sign in
Merge pull request #1 from paluh/master

Simple "string" representation for number literals

commit90f15465397d313fa903b09b44b82fce53e88a7f authorJan Vincent Liwanag <jvliwanag@gmail.com> dateWed 27 Nov 2019, 09:41 (7 years ago) parentbaffd1805b308f
13 files changed+187−18
spago.dhall+4 src/Literal.purs−16 src/Literals.purs+14 src/Literals/Boolean.purs+17 src/Literals/Int.purs+53 src/Literals/Literal.purs+8 src/Literals/Null.js+1 src/Literals/Null.purs+5 src/Literals/Number.purs+46 src/Literals/String.purs+15 src/Literals/Undefined.js+1 src/Literals/Undefined.purs+5 test/Main.purs+18−2
spago.dhall+4
@@ -8,8 +8,12 @@ You can edit this file as you like.
88 [ "assert"
99 , "effect"
1010 , "console"
11+ , "integers"
12+ , "numbers"
13+ , "partial"
1114 , "psci-support"
1215 , "unsafe-coerce"
16+ , "typelevel-prelude"
1317 ]
1418, packages =
1519 ./packages.dhall
src/Literal.pursdeleted−16
@@ -1,16 +0,0 @@
1−module Literal
2− ( Literal
3− , literal
4− , toString
5− ) where
6−
7−import Data.Symbol (class IsSymbol, SProxy(..), reflectSymbol)
8−import Unsafe.Coerce (unsafeCoerce)
9−
10−foreign import data Literal :: Symbol -> Type
11−
12−literal :: forall sym. IsSymbol sym => Literal sym
13−literal = unsafeCoerce (reflectSymbol (SProxy :: SProxy sym))
14−
15−toString :: forall sym. Literal sym -> String
16−toString = unsafeCoerce
src/Literals.pursnew file+14
@@ -0,0 +1,14 @@
1+module Literals
2+ ( module Boolean
3+ , module Int
4+ , module Literal
5+ , module Number
6+ , module String
7+ ) where
8+
9+import Literals.Boolean (BooleanLit, false_, true_) as Boolean
10+import Literals.Int (class Digit, class Int, class Int', IntLit, intLit) as Int
11+import Literals.Literal (Literal, toValue) as Literal
12+import Literals.Number (class Number, class Number', NumberLit, numberLit) as Number
13+import Literals.String (StringLit, stringLit) as String
14+
src/Literals/Boolean.pursnew file+17
@@ -0,0 +1,17 @@
1+module Literals.Boolean
2+ ( BooleanLit
3+ , false_
4+ , true_
5+ ) where
6+
7+import Literals.Literal (Literal)
8+import Unsafe.Coerce (unsafeCoerce)
9+
10+type BooleanLit sym = Literal Boolean sym
11+
12+true_ :: BooleanLit "true"
13+true_ = unsafeCoerce true
14+
15+false_ :: BooleanLit "false"
16+false_ = unsafeCoerce false
17+
src/Literals/Int.pursnew file+53
@@ -0,0 +1,53 @@
1+module Literals.Int
2+ ( IntLit
3+ , IntegerPart
4+ , Sign
5+ , class Digit
6+ , class Int
7+ , class Int'
8+ , intLit
9+ , kind IntPart
10+ ) where
11+
12+import Prelude
13+
14+import Data.Int (fromString)
15+import Data.Maybe (fromJust)
16+import Data.Symbol (class IsSymbol)
17+import Literals.Literal (Literal)
18+import Partial.Unsafe (unsafePartial)
19+import Prim.Symbol (class Cons)
20+import Type.Prelude (SProxy(..), reflectSymbol)
21+import Unsafe.Coerce (unsafeCoerce)
22+
23+class Digit (s :: Symbol)
24+
25+instance digit0 :: Digit "0"
26+else instance digit1 :: Digit "1"
27+else instance digit2 :: Digit "2"
28+else instance digit3 :: Digit "3"
29+else instance digit4 :: Digit "4"
30+else instance digit5 :: Digit "5"
31+else instance digit6 :: Digit "6"
32+else instance digit7 :: Digit "7"
33+else instance digit8 :: Digit "8"
34+else instance digit9 :: Digit "9"
35+
36+foreign import kind IntPart
37+foreign import data Sign :: IntPart
38+foreign import data IntegerPart :: IntPart
39+
40+class Int (sym :: Symbol)
41+instance intInstance :: (Int' h t Sign, Cons h t s) => Int s
42+
43+class Int' (head :: Symbol) (tail :: Symbol) (part :: IntPart)
44+
45+instance signPart :: (Cons h' t' t, Int' h' t' IntegerPart) => Int' "-" t Sign
46+else instance signPartEmpty :: (Int' h t IntegerPart) => Int' h t Sign
47+else instance lastIntegerPart :: (Digit h) => Int' h "" IntegerPart
48+else instance digitIntegerPart :: (Digit h, Cons h' t' t, Int' h' t' IntegerPart) => Int' h t IntegerPart
49+
50+type IntLit sym = Literal Int sym
51+
52+intLit :: forall sym. IsSymbol sym => Int sym => IntLit sym
53+intLit = unsafeCoerce $ unsafePartial $ fromJust $ fromString $ reflectSymbol (SProxy :: SProxy sym)
src/Literals/Literal.pursnew file+8
@@ -0,0 +1,8 @@
1+module Literals.Literal where
2+
3+import Unsafe.Coerce (unsafeCoerce)
4+
5+foreign import data Literal :: Type -> Symbol -> Type
6+
7+toValue :: ∀ s a. Literal a s -> a
8+toValue = unsafeCoerce
src/Literals/Null.jsnew file+1
@@ -0,0 +1 @@
1+exports.null = null;
src/Literals/Null.pursnew file+5
@@ -0,0 +1,5 @@
1+module Literals.Null where
2+
3+foreign import data Null :: Type
4+
5+foreign import null :: Null
src/Literals/Number.pursnew file+46
@@ -0,0 +1,46 @@
1+module Literals.Number
2+ ( FractionalPart
3+ , IntegerPart
4+ , NumberLit
5+ , Sign
6+ , class Number
7+ , class Number'
8+ , kind NumberPart
9+ , numberLit
10+ ) where
11+
12+import Prelude
13+
14+import Data.Maybe (fromJust)
15+import Data.Number (fromString)
16+import Data.Symbol (class IsSymbol, SProxy(..))
17+import Literals.Int (class Digit)
18+import Literals.Literal (Literal)
19+import Partial.Unsafe (unsafePartial)
20+import Prim.Symbol (class Cons)
21+import Type.Prelude (reflectSymbol)
22+import Unsafe.Coerce (unsafeCoerce)
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 IntegerPart :: NumberPart
31+foreign import data FractionalPart :: NumberPart
32+
33+class Number' (head :: Symbol) (tail :: Symbol) (part :: NumberPart)
34+
35+instance signPart :: (Cons h' t' t, Number' h' t' IntegerPart) => Number' "-" t Sign
36+else instance signPartEmpty :: (Number' h t IntegerPart) => Number' h t Sign
37+else instance pointIntegerPart :: (Cons h' t' t, Number' h' t' FractionalPart) => Number' "." t IntegerPart
38+else instance lastFractionalPart :: (Digit h) => Number' h "" FractionalPart
39+else instance digitIntegerPart :: (Digit h, Cons h' t' t, Number' h' t' IntegerPart) => Number' h t IntegerPart
40+else instance digitFractionalPart :: (Digit h, Cons h' t' t, Number' h' t' FractionalPart) => Number' h t FractionalPart
41+
42+type NumberLit sym = Literal Number sym
43+
44+numberLit :: forall sym. IsSymbol sym => Number sym => NumberLit sym
45+numberLit = unsafeCoerce $ unsafePartial $ fromJust $ fromString $ reflectSymbol (SProxy :: SProxy sym)
46+
src/Literals/String.pursnew file+15
@@ -0,0 +1,15 @@
1+module Literals.String
2+ ( stringLit
3+ , StringLit
4+ ) where
5+
6+import Data.Symbol (class IsSymbol, SProxy(..), reflectSymbol)
7+import Literals.Literal (Literal)
8+import Unsafe.Coerce (unsafeCoerce)
9+
10+type StringLit sym = Literal String sym
11+
12+stringLit :: forall sym. IsSymbol sym => StringLit sym
13+stringLit = unsafeCoerce (reflectSymbol (SProxy :: SProxy sym))
14+
15+
src/Literals/Undefined.jsnew file+1
@@ -0,0 +1 @@
1+exports.undefined = undefined;
src/Literals/Undefined.pursnew file+5
@@ -0,0 +1,5 @@
1+module Literals.Undefined where
2+
3+foreign import data Undefined :: Type
4+
5+foreign import undefined :: Undefined
test/Main.purs+18−2
@@ -3,13 +3,29 @@ module Test.Main where
33import Prelude
44
55import Effect (Effect)
6−import Literal (Literal, literal)
6+import Literals (NumberLit, StringLit, IntLit, intLit, numberLit, stringLit)
77import Test.Assert (assertEqual)
88import Unsafe.Coerce (unsafeCoerce)
99
10+
1011main :: Effect Unit
1112main = do
1213 assertEqual
13− { actual: unsafeCoerce (literal :: Literal "foo")
14+ { actual: unsafeCoerce (stringLit :: StringLit "foo")
1415 , expected: "foo"
1516 }
17+ assertEqual
18+ { actual: unsafeCoerce (numberLit :: NumberLit "8.0")
19+ , expected: 8.0
20+ }
21+ assertEqual { actual: unsafeCoerce (numberLit :: NumberLit "-8.0")
22+ , expected: -8.0
23+ }
24+ assertEqual
25+ { actual: unsafeCoerce (intLit :: IntLit "8")
26+ , expected: 8
27+ }
28+ assertEqual { actual: unsafeCoerce (intLit :: IntLit "-8")
29+ , expected: -8
30+ }
31+