Add base Literal type. Fix exports and type names. Add IntLit.

This commit is contained in:
Tomasz Rybarczyk 2019-11-27 00:27:50 +01:00
parent 1b1c85266d
commit 05b308f295
8 changed files with 117 additions and 51 deletions

View File

@ -8,6 +8,7 @@ You can edit this file as you like.
[ "assert"
, "effect"
, "console"
, "integers"
, "numbers"
, "partial"
, "psci-support"

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

View File

@ -1,13 +1,17 @@
module Literals.Boolean where
module Literals.Boolean
( BooleanLit
, false_
, true_
) where
import Literals.Literal (Literal)
import Unsafe.Coerce (unsafeCoerce)
data True
data False
type BooleanLit sym = Literal Boolean sym
true_ :: True
true_ :: BooleanLit "true"
true_ = unsafeCoerce true
false_ :: False
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

View File

@ -1,26 +1,26 @@
module Literals.Number where
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 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"
class Number (sym :: Symbol)
instance numberInstance :: (Number' h t Sign, Cons h t s) => Number s
@ -35,16 +35,12 @@ 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 lastIntegerPart :: (Digit h) => Number' h "" IntegerPart
else instance digitIntegerPart :: (Digit h, Cons h' t' t, Number' h' t' IntegerPart) => Number' h 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
foreign import data Literal :: Symbol -> Type
type NumberLit sym = Literal Number sym
literal :: forall s. IsSymbol s => Number s => Literal s
literal = (unsafeCoerce (unsafePartial (fromJust (fromString (reflectSymbol (SProxy :: SProxy s))))))
toNumber :: forall s. Literal s -> Number
toNumber = unsafeCoerce
numberLit :: forall sym. IsSymbol sym => Number sym => NumberLit sym
numberLit = unsafeCoerce $ unsafePartial $ fromJust $ fromString $ reflectSymbol (SProxy :: SProxy sym)

View File

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

View File

@ -3,8 +3,7 @@ module Test.Main where
import Prelude
import Effect (Effect)
import Literals.Number (Literal, literal) as Number
import Literals.String (Literal, literal) as String
import Literals (NumberLit, StringLit, IntLit, intLit, numberLit, stringLit)
import Test.Assert (assertEqual)
import Unsafe.Coerce (unsafeCoerce)
@ -12,28 +11,21 @@ import Unsafe.Coerce (unsafeCoerce)
main :: Effect Unit
main = do
assertEqual
{ actual: unsafeCoerce (String.literal :: String.Literal "foo")
{ actual: unsafeCoerce (stringLit :: StringLit "foo")
, expected: "foo"
}
assertEqual
{ actual: unsafeCoerce (Number.literal :: Number.Literal "8")
{ actual: unsafeCoerce (numberLit :: NumberLit "8.0")
, expected: 8.0
}
assertEqual
{ actual: unsafeCoerce (Number.literal :: Number.Literal "-8")
assertEqual { actual: unsafeCoerce (numberLit :: NumberLit "-8.0")
, expected: -8.0
}
assertEqual
{ actual: unsafeCoerce (Number.literal :: Number.Literal "100.0")
, expected: 100.0
{ actual: unsafeCoerce (intLit :: IntLit "8")
, expected: 8
}
assertEqual
{ actual: unsafeCoerce (Number.literal :: Number.Literal "-100.0")
, expected: -100.0
}
assertEqual
{ actual: unsafeCoerce (Number.literal :: Number.Literal "0.0")
, expected: 0.0
assertEqual { actual: unsafeCoerce (intLit :: IntLit "-8")
, expected: -8
}