git.iko.soy/purescript-literals
on main help sign in
15 files changed+253−78
since splitsnapshots
unifiedsplit
LICENSE+21 bower.json+27 packages.dhall+2−3 spago.dhall+15−19 src/Literals.purs+13 src/Literals/Boolean.purs+9−5 src/Literals/Int.purs+54 src/Literals/Literal.purs+15 src/Literals/Null.js+1 src/Literals/Null.purs+17 src/Literals/Number.purs+21−26 src/Literals/String.purs+8−11 src/Literals/Undefined.js+1 src/Literals/Undefined.purs+19 test/Main.purs+30−14
LICENSEnew file+21
@@ -0,0 +1,21 @@
1+MIT License
2+
3+Copyright (c) 2020 Jan Vincent Liwanag
4+
5+Permission is hereby granted, free of charge, to any person obtaining a copy
6+of this software and associated documentation files (the "Software"), to deal
7+in the Software without restriction, including without limitation the rights
8+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+copies of the Software, and to permit persons to whom the Software is
10+furnished to do so, subject to the following conditions:
11+
12+The above copyright notice and this permission notice shall be included in all
13+copies or substantial portions of the Software.
14+
15+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+SOFTWARE.
bower.jsonnew file+27
@@ -0,0 +1,27 @@
1+{
2+ "name": "purescript-literals",
3+ "license": [
4+ "MIT"
5+ ],
6+ "repository": {
7+ "type": "git",
8+ "url": "https://github.com/rowtype-yoga/purescript-literals.git"
9+ },
10+ "ignore": [
11+ "**/.*",
12+ "node_modules",
13+ "bower_components",
14+ "output"
15+ ],
16+ "dependencies": {
17+ "purescript-assert": "^v6.0.0",
18+ "purescript-effect": "^v4.0.0",
19+ "purescript-integers": "^v6.0.0",
20+ "purescript-maybe": "^v6.0.0",
21+ "purescript-numbers": "^v9.0.0",
22+ "purescript-partial": "^v4.0.0",
23+ "purescript-prelude": "^v6.0.0",
24+ "purescript-typelevel-prelude": "^v7.0.0",
25+ "purescript-unsafe-coerce": "^v6.0.0"
26+ }
27+}
packages.dhall+2−3
@@ -116,10 +116,9 @@ let additions =
116116 }
117117-------------------------------
118118-}
119−
120−
121119let upstream =
122− https://github.com/purescript/package-sets/releases/download/psc-0.13.4-20191110/packages.dhall sha256:563a7f694e18e6399f7f6d01f5b7e3c3345781655d99945768f48e458feb93a4
120+ https://github.com/purescript/package-sets/releases/download/psc-0.15.2-20220530/packages.dhall
121+ sha256:15dd8041480502850e4043ea2977ed22d6ab3fc24d565211acde6f8c5152a799
123122
124123let overrides = {=}
125124
spago.dhall+15−19
@@ -1,21 +1,17 @@
1−{-
2−Welcome to a Spago project!
3−You can edit this file as you like.
4−-}
5−{ name =
6− "literal"
1+{ name = "literals"
2+, license = "MIT"
3+, repository = "https://github.com/rowtype-yoga/purescript-literals.git"
74, dependencies =
8− [ "assert"
9− , "effect"
10− , "console"
11− , "numbers"
12− , "partial"
13− , "psci-support"
14− , "unsafe-coerce"
15− , "typelevel-prelude"
16− ]
17−, packages =
18− ./packages.dhall
19−, sources =
20− [ "src/**/*.purs", "test/**/*.purs" ]
5+ [ "assert"
6+ , "effect"
7+ , "integers"
8+ , "maybe"
9+ , "numbers"
10+ , "partial"
11+ , "prelude"
12+ , "typelevel-prelude"
13+ , "unsafe-coerce"
14+ ]
15+, packages = ./packages.dhall
16+, sources = [ "src/**/*.purs", "test/**/*.purs" ]
2117}
src/Literals.pursnew file+13
@@ -0,0 +1,13 @@
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
src/Literals/Boolean.purs+9−5
@@ -1,13 +1,17 @@
1−module Literals.Boolean where
1+module Literals.Boolean
2+ ( BooleanLit
3+ , false_
4+ , true_
5+ ) where
26
7+import Literals.Literal (Literal)
38import Unsafe.Coerce (unsafeCoerce)
49
5−data True
6−data False
10+type BooleanLit sym = Literal Boolean sym
711
8−true_ :: True
12+true_ :: BooleanLit "true"
913true_ = unsafeCoerce true
1014
11−false_ :: False
15+false_ :: BooleanLit "false"
1216false_ = unsafeCoerce false
1317
src/Literals/Int.pursnew file+54
@@ -0,0 +1,54 @@
1+module Literals.Int
2+ ( IntLit
3+ , IntegerPart
4+ , Sign
5+ , class Digit
6+ , class Int
7+ , class Int'
8+ , intLit
9+ , 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 (reflectSymbol)
21+import Type.Proxy (Proxy(..))
22+import Unsafe.Coerce (unsafeCoerce)
23+
24+class Digit (s :: Symbol)
25+
26+instance digit0 :: Digit "0"
27+else instance digit1 :: Digit "1"
28+else instance digit2 :: Digit "2"
29+else instance digit3 :: Digit "3"
30+else instance digit4 :: Digit "4"
31+else instance digit5 :: Digit "5"
32+else instance digit6 :: Digit "6"
33+else instance digit7 :: Digit "7"
34+else instance digit8 :: Digit "8"
35+else instance digit9 :: Digit "9"
36+
37+data IntPart
38+foreign import data Sign :: IntPart
39+foreign import data IntegerPart :: IntPart
40+
41+class Int (sym :: Symbol)
42+instance intInstance :: (Int' h t Sign, Cons h t s) => Int s
43+
44+class Int' (head :: Symbol) (tail :: Symbol) (part :: IntPart)
45+
46+instance signPart :: (Cons h' t' t, Int' h' t' IntegerPart) => Int' "-" t Sign
47+else instance signPartEmpty :: (Int' h t IntegerPart) => Int' h t Sign
48+else instance lastIntegerPart :: (Digit h) => Int' h "" IntegerPart
49+else instance digitIntegerPart :: (Digit h, Cons h' t' t, Int' h' t' IntegerPart) => Int' h t IntegerPart
50+
51+type IntLit sym = Literal Int sym
52+
53+intLit :: forall sym. IsSymbol sym => Int sym => IntLit sym
54+intLit = unsafeCoerce $ unsafePartial $ fromJust $ fromString $ reflectSymbol (Proxy :: Proxy sym)
src/Literals/Literal.pursnew file+15
@@ -0,0 +1,15 @@
1+module Literals.Literal where
2+
3+import Prelude
4+
5+import Unsafe.Coerce (unsafeCoerce)
6+
7+foreign import data Literal :: Type -> Symbol -> Type
8+
9+instance literalEq :: Eq (Literal typ sym) where
10+ eq _ _ = true
11+instance literalShow :: Show typ => Show (Literal typ sym) where
12+ show a = "(Literal " <> (show $ toValue a) <> ")"
13+
14+toValue :: ∀ s a. Literal a s -> a
15+toValue = unsafeCoerce
src/Literals/Null.jsnew file+1
@@ -0,0 +1 @@
1+export _null = null;
src/Literals/Null.pursnew file+17
@@ -0,0 +1,17 @@
1+module Literals.Null
2+ ( Null
3+ , null
4+ )
5+where
6+
7+import Prelude
8+
9+foreign import data Null :: Type
10+
11+foreign import _null :: Null
12+
13+null :: Null
14+null = _null
15+
16+instance showNull :: Show Null where
17+ show _ = "null"
src/Literals/Number.purs+21−26
@@ -1,31 +1,31 @@
1−module Literals.Number where
1+module Literals.Number
2+ ( FractionalPart
3+ , IntegerPart
4+ , NumberLit
5+ , Sign
6+ , class Number
7+ , class Number'
8+ , NumberPart
9+ , numberLit
10+ ) where
11+
12+import Prelude
213
314import Data.Maybe (fromJust)
415import Data.Number (fromString)
5−import Data.Symbol (class IsSymbol, SProxy(..))
16+import Data.Symbol (class IsSymbol)
17+import Literals.Int (class Digit)
18+import Literals.Literal (Literal)
619import Partial.Unsafe (unsafePartial)
720import Prim.Symbol (class Cons)
8−import Type.Prelude (reflectSymbol)
21+import Type.Prelude (reflectSymbol, Proxy(..))
922import Unsafe.Coerce (unsafeCoerce)
1023
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−
2424class Number (sym :: Symbol)
2525
2626instance numberInstance :: (Number' h t Sign, Cons h t s) => Number s
2727
28−foreign import kind NumberPart
28+data NumberPart
2929foreign import data Sign :: NumberPart
3030foreign import data IntegerPart :: NumberPart
3131foreign import data FractionalPart :: NumberPart
@@ -35,16 +35,11 @@ class Number' (head :: Symbol) (tail :: Symbol) (part :: NumberPart)
3535instance signPart :: (Cons h' t' t, Number' h' t' IntegerPart) => Number' "-" t Sign
3636else instance signPartEmpty :: (Number' h t IntegerPart) => Number' h t Sign
3737else instance pointIntegerPart :: (Cons h' t' t, Number' h' t' FractionalPart) => Number' "." t IntegerPart
38−else instance lastIntegerPart :: (Digit h) ⇒ Number' h "" IntegerPart
38+else instance lastFractionalPart :: (Digit h) => Number' h "" FractionalPart
3939else instance digitIntegerPart :: (Digit h, Cons h' t' t, Number' h' t' IntegerPart) => Number' h t IntegerPart
40−else instance lastFractionalPart :: (Digit h) ⇒ Number' h "" FractionalPart
4140else instance digitFractionalPart :: (Digit h, Cons h' t' t, Number' h' t' FractionalPart) => Number' h t FractionalPart
4241
43−foreign import data Literal ∷ Symbol → Type
44−
45−literal :: ∀ s. IsSymbol s ⇒ Number s => Literal s
46−literal = (unsafeCoerce (unsafePartial (fromJust (fromString (reflectSymbol (SProxy :: SProxy s))))))
47−
48−toNumber ∷ ∀ s. Literal s → Number
49−toNumber = unsafeCoerce
42+type NumberLit sym = Literal Number sym
5043
44+numberLit :: forall sym. IsSymbol sym => Number sym => NumberLit sym
45+numberLit = unsafeCoerce $ unsafePartial $ fromJust $ fromString $ reflectSymbol (Proxy :: Proxy sym)
src/Literals/String.purs+8−11
@@ -1,17 +1,14 @@
11module Literals.String
2− ( Literal
3− , literal
4− , toString
2+ ( stringLit
3+ , StringLit
54 ) where
65
7−import Data.Symbol (class IsSymbol, SProxy(..), reflectSymbol)
6+import Data.Symbol (class IsSymbol, reflectSymbol)
7+import Type.Proxy (Proxy(..))
8+import Literals.Literal (Literal)
89import Unsafe.Coerce (unsafeCoerce)
910
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
11+type StringLit sym = Literal String sym
1712
13+stringLit :: forall sym. IsSymbol sym => StringLit sym
14+stringLit = unsafeCoerce (reflectSymbol (Proxy :: Proxy sym))
src/Literals/Undefined.jsnew file+1
@@ -0,0 +1 @@
1+export const _undefined = undefined;
src/Literals/Undefined.pursnew file+19
@@ -0,0 +1,19 @@
1+module Literals.Undefined
2+ ( Undefined
3+ , undefined
4+ )
5+where
6+
7+import Prelude
8+
9+foreign import data Undefined :: Type
10+
11+foreign import _undefined :: Undefined
12+
13+undefined :: Undefined
14+undefined = _undefined
15+
16+instance undefinedEq :: Eq Undefined where
17+ eq _ _ = true
18+instance undefinedShow :: Show Undefined where
19+ show _ = "Undefined"
test/Main.purs+30−14
@@ -3,37 +3,53 @@ module Test.Main where
33import Prelude
44
55import Effect (Effect)
6−import Literals.Number (Literal, literal) as Number
7−import Literals.String (Literal, literal) as String
8−import Test.Assert (assertEqual)
6+import Literals (NumberLit, StringLit, IntLit, intLit, numberLit, stringLit)
7+import Literals.Undefined (undefined)
8+import Test.Assert (assertEqual, assertTrue)
99import Unsafe.Coerce (unsafeCoerce)
1010
1111
1212main :: Effect Unit
1313main = do
1414 assertEqual
15− { actual: unsafeCoerce (String.literal :: String.Literal "foo")
15+ { actual: unsafeCoerce (stringLit :: StringLit "foo")
1616 , expected: "foo"
1717 }
1818 assertEqual
19− { actual: unsafeCoerce (Number.literal :: Number.Literal "8")
19+ { actual: unsafeCoerce (numberLit :: NumberLit "8.0")
2020 , expected: 8.0
2121 }
2222 assertEqual
23− { actual: unsafeCoerce (Number.literal :: Number.Literal "-8")
23+ { actual: unsafeCoerce (numberLit :: NumberLit "-8.0")
2424 , expected: -8.0
2525 }
2626 assertEqual
27− { actual: unsafeCoerce (Number.literal :: Number.Literal "100.0")
28− , expected: 100.0
27+ { actual: unsafeCoerce (intLit :: IntLit "8")
28+ , expected: 8
2929 }
3030 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
31+ { actual: unsafeCoerce (intLit :: IntLit "-8")
32+ , expected: -8
3733 }
3834
35+ -- Eq instance
36+ assertTrue $ undefined == undefined
37+ assertTrue $ (stringLit :: StringLit "foo") == (stringLit :: StringLit "foo")
3938
39+ -- Show instance
40+ assertEqual
41+ { actual: show (stringLit :: StringLit "foo")
42+ , expected: "(Literal \"foo\")"
43+ }
44+ assertEqual
45+ { actual: show (numberLit :: NumberLit "8.0")
46+ , expected: "(Literal 8.0)"
47+ }
48+ assertEqual
49+ { actual: show (intLit :: IntLit "8")
50+ , expected: "(Literal 8)"
51+ }
52+ assertEqual
53+ { actual: show undefined
54+ , expected: "Undefined"
55+ }