Merge pull request #1 from paluh/master

Simple "string" representation for number literals
This commit is contained in:
Jan Vincent Liwanag 2019-11-27 09:41:52 +08:00 committed by GitHub
commit 90f1546539
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 187 additions and 18 deletions

View File

@ -8,8 +8,12 @@ You can edit this file as you like.
[ "assert"
, "effect"
, "console"
, "integers"
, "numbers"
, "partial"
, "psci-support"
, "unsafe-coerce"
, "typelevel-prelude"
]
, packages =
./packages.dhall

View File

@ -1,16 +0,0 @@
module Literal
( Literal
, literal
, toString
) where
import Data.Symbol (class IsSymbol, SProxy(..), reflectSymbol)
import Unsafe.Coerce (unsafeCoerce)
foreign import data Literal :: Symbol -> Type
literal :: forall sym. IsSymbol sym => Literal sym
literal = unsafeCoerce (reflectSymbol (SProxy :: SProxy sym))
toString :: forall sym. Literal sym -> String
toString = unsafeCoerce

14
src/Literals.purs Normal file
View File

@ -0,0 +1,14 @@
module Literals
( module Boolean
, module Int
, module Literal
, module Number
, module String
) where
import Literals.Boolean (BooleanLit, false_, true_) as Boolean
import Literals.Int (class Digit, class Int, class Int', IntLit, intLit) as Int
import Literals.Literal (Literal, toValue) as Literal
import Literals.Number (class Number, class Number', NumberLit, numberLit) as Number
import Literals.String (StringLit, stringLit) as String

17
src/Literals/Boolean.purs Normal file
View File

@ -0,0 +1,17 @@
module Literals.Boolean
( BooleanLit
, false_
, true_
) where
import Literals.Literal (Literal)
import Unsafe.Coerce (unsafeCoerce)
type BooleanLit sym = Literal Boolean sym
true_ :: BooleanLit "true"
true_ = unsafeCoerce true
false_ :: BooleanLit "false"
false_ = unsafeCoerce false

53
src/Literals/Int.purs Normal file
View File

@ -0,0 +1,53 @@
module Literals.Int
( IntLit
, IntegerPart
, Sign
, class Digit
, class Int
, class Int'
, intLit
, kind IntPart
) where
import Prelude
import Data.Int (fromString)
import Data.Maybe (fromJust)
import Data.Symbol (class IsSymbol)
import Literals.Literal (Literal)
import Partial.Unsafe (unsafePartial)
import Prim.Symbol (class Cons)
import Type.Prelude (SProxy(..), reflectSymbol)
import Unsafe.Coerce (unsafeCoerce)
class Digit (s :: Symbol)
instance digit0 :: Digit "0"
else instance digit1 :: Digit "1"
else instance digit2 :: Digit "2"
else instance digit3 :: Digit "3"
else instance digit4 :: Digit "4"
else instance digit5 :: Digit "5"
else instance digit6 :: Digit "6"
else instance digit7 :: Digit "7"
else instance digit8 :: Digit "8"
else instance digit9 :: Digit "9"
foreign import kind IntPart
foreign import data Sign :: IntPart
foreign import data IntegerPart :: IntPart
class Int (sym :: Symbol)
instance intInstance :: (Int' h t Sign, Cons h t s) => Int s
class Int' (head :: Symbol) (tail :: Symbol) (part :: IntPart)
instance signPart :: (Cons h' t' t, Int' h' t' IntegerPart) => Int' "-" t Sign
else instance signPartEmpty :: (Int' h t IntegerPart) => Int' h t Sign
else instance lastIntegerPart :: (Digit h) => Int' h "" IntegerPart
else instance digitIntegerPart :: (Digit h, Cons h' t' t, Int' h' t' IntegerPart) => Int' h t IntegerPart
type IntLit sym = Literal Int sym
intLit :: forall sym. IsSymbol sym => Int sym => IntLit sym
intLit = unsafeCoerce $ unsafePartial $ fromJust $ fromString $ reflectSymbol (SProxy :: SProxy sym)

View File

@ -0,0 +1,8 @@
module Literals.Literal where
import Unsafe.Coerce (unsafeCoerce)
foreign import data Literal :: Type -> Symbol -> Type
toValue :: ∀ s a. Literal a s -> a
toValue = unsafeCoerce

1
src/Literals/Null.js Normal file
View File

@ -0,0 +1 @@
exports.null = null;

5
src/Literals/Null.purs Normal file
View File

@ -0,0 +1,5 @@
module Literals.Null where
foreign import data Null :: Type
foreign import null :: Null

46
src/Literals/Number.purs Normal file
View File

@ -0,0 +1,46 @@
module Literals.Number
( FractionalPart
, IntegerPart
, NumberLit
, Sign
, class Number
, class Number'
, kind NumberPart
, numberLit
) where
import Prelude
import Data.Maybe (fromJust)
import Data.Number (fromString)
import Data.Symbol (class IsSymbol, SProxy(..))
import Literals.Int (class Digit)
import Literals.Literal (Literal)
import Partial.Unsafe (unsafePartial)
import Prim.Symbol (class Cons)
import Type.Prelude (reflectSymbol)
import Unsafe.Coerce (unsafeCoerce)
class Number (sym :: Symbol)
instance numberInstance :: (Number' h t Sign, Cons h t s) => Number s
foreign import kind NumberPart
foreign import data Sign :: NumberPart
foreign import data IntegerPart :: NumberPart
foreign import data FractionalPart :: NumberPart
class Number' (head :: Symbol) (tail :: Symbol) (part :: NumberPart)
instance signPart :: (Cons h' t' t, Number' h' t' IntegerPart) => Number' "-" t Sign
else instance signPartEmpty :: (Number' h t IntegerPart) => Number' h t Sign
else instance pointIntegerPart :: (Cons h' t' t, Number' h' t' FractionalPart) => Number' "." t IntegerPart
else instance lastFractionalPart :: (Digit h) => Number' h "" FractionalPart
else instance digitIntegerPart :: (Digit h, Cons h' t' t, Number' h' t' IntegerPart) => Number' h t IntegerPart
else instance digitFractionalPart :: (Digit h, Cons h' t' t, Number' h' t' FractionalPart) => Number' h t FractionalPart
type NumberLit sym = Literal Number sym
numberLit :: forall sym. IsSymbol sym => Number sym => NumberLit sym
numberLit = unsafeCoerce $ unsafePartial $ fromJust $ fromString $ reflectSymbol (SProxy :: SProxy sym)

15
src/Literals/String.purs Normal file
View File

@ -0,0 +1,15 @@
module Literals.String
( stringLit
, StringLit
) where
import Data.Symbol (class IsSymbol, SProxy(..), reflectSymbol)
import Literals.Literal (Literal)
import Unsafe.Coerce (unsafeCoerce)
type StringLit sym = Literal String sym
stringLit :: forall sym. IsSymbol sym => StringLit sym
stringLit = unsafeCoerce (reflectSymbol (SProxy :: SProxy sym))

View File

@ -0,0 +1 @@
exports.undefined = undefined;

View File

@ -0,0 +1,5 @@
module Literals.Undefined where
foreign import data Undefined :: Type
foreign import undefined :: Undefined

View File

@ -3,13 +3,29 @@ module Test.Main where
import Prelude
import Effect (Effect)
import Literal (Literal, literal)
import Literals (NumberLit, StringLit, IntLit, intLit, numberLit, stringLit)
import Test.Assert (assertEqual)
import Unsafe.Coerce (unsafeCoerce)
main :: Effect Unit
main = do
assertEqual
{ actual: unsafeCoerce (literal :: Literal "foo")
{ actual: unsafeCoerce (stringLit :: StringLit "foo")
, expected: "foo"
}
assertEqual
{ actual: unsafeCoerce (numberLit :: NumberLit "8.0")
, expected: 8.0
}
assertEqual { actual: unsafeCoerce (numberLit :: NumberLit "-8.0")
, expected: -8.0
}
assertEqual
{ actual: unsafeCoerce (intLit :: IntLit "8")
, expected: 8
}
assertEqual { actual: unsafeCoerce (intLit :: IntLit "-8")
, expected: -8
}