-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Divide (closed) Primitives and (opened) Builtins #119
base: master
Are you sure you want to change the base?
Changes from all commits
25058e2
a5812ea
36ca36d
3175db8
ef64980
96228c8
cbbe521
659bdb6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,8 +16,8 @@ encodePrims x = E.object | |
, ("int", E.int x.int) | ||
, ("float", E.float x.float) | ||
, ("text", E.string x.text) | ||
, ("time", Iso.encode x.time) | ||
, ("value", Basics.identity x.value) | ||
, ("time", Iso.encode x.time) | ||
, ("value", Basics.identity x.value) | ||
Comment on lines
-19
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. related to todo of making implementation less naive |
||
, ("maybe", (elmStreetEncodeMaybe E.int) x.maybe) | ||
, ("result", (elmStreetEncodeEither E.int E.string) x.result) | ||
, ("pair", (elmStreetEncodePair (E.string << String.fromChar) E.bool) x.pair) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,8 @@ module Core.Types exposing (..) | |
import Time exposing (Posix) | ||
import Json.Decode exposing (Value) | ||
|
||
type alias ElmStreetNonEmptyList a = (a, List a) | ||
|
||
Comment on lines
+6
to
+7
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is now required as we can't produce type annotation |
||
|
||
type alias Prims = | ||
{ unit : () | ||
|
@@ -11,14 +13,14 @@ type alias Prims = | |
, int : Int | ||
, float : Float | ||
, text : String | ||
, time : Posix | ||
, value : Value | ||
, time : Posix | ||
, value : Value | ||
Comment on lines
+16
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. related to todo of making implementation less naive |
||
, maybe : Maybe Int | ||
, result : Result Int String | ||
, pair : (Char, Bool) | ||
, triple : (Char, Bool, List Int) | ||
, list : List Int | ||
, nonEmpty : (Int, List Int) | ||
, nonEmpty : ElmStreetNonEmptyList Int | ||
} | ||
|
||
type MyUnit | ||
|
@@ -116,5 +118,5 @@ type alias OneType = | |
, user : User | ||
, guests : List Guest | ||
, userRequest : UserRequest | ||
, nonEmpty : (MyUnit, List MyUnit) | ||
, nonEmpty : ElmStreetNonEmptyList MyUnit | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,9 +5,10 @@ converted to this AST which later is going to be pretty-printed. | |
module Elm.Ast | ||
( ElmDefinition (..) | ||
|
||
, ElmPrim (..) | ||
, ElmRecord (..) | ||
, ElmType (..) | ||
, ElmPrim (..) | ||
, ElmBuiltin (..) | ||
|
||
, ElmRecordField (..) | ||
, ElmConstructor (..) | ||
|
@@ -25,9 +26,10 @@ import Data.Text (Text) | |
|
||
-- | Elm data type definition. | ||
data ElmDefinition | ||
= DefRecord !ElmRecord | ||
= DefPrim !ElmPrim | ||
| DefRecord !ElmRecord | ||
| DefBuiltin !ElmBuiltin | ||
| DefType !ElmType | ||
| DefPrim !ElmPrim | ||
deriving (Show) | ||
|
||
-- | AST for @record type alias@ in Elm. | ||
|
@@ -70,7 +72,7 @@ isEnum ElmType{..} = null elmTypeVars && null (foldMap elmConstructorFields elmT | |
getConstructorNames :: ElmType -> [Text] | ||
getConstructorNames ElmType{..} = map elmConstructorName $ toList elmTypeConstructors | ||
|
||
-- | Primitive elm types; hardcoded by the language. | ||
-- | Primitive elm types which are parts of a language | ||
data ElmPrim | ||
= ElmUnit -- ^ @()@ type in elm | ||
| ElmNever -- ^ @Never@ type in elm, analogous to Void in Haskell | ||
|
@@ -79,25 +81,35 @@ data ElmPrim | |
| ElmInt -- ^ @Int@ | ||
| ElmFloat -- ^ @Float@ | ||
| ElmString -- ^ @String@ | ||
| ElmTime -- ^ @Posix@ in elm, @UTCTime@ in Haskell | ||
| ElmValue -- ^ @Json.Encode.Value@ in elm, @Data.Aeson.Value@ in Haskell | ||
| ElmMaybe !TypeRef -- ^ @Maybe T@ | ||
| ElmResult !TypeRef !TypeRef -- ^ @Result A B@ in elm | ||
| ElmPair !TypeRef !TypeRef -- ^ @(A, B)@ in elm | ||
| ElmTriple !TypeRef !TypeRef !TypeRef -- ^ @(A, B, C)@ in elm | ||
| ElmList !TypeRef -- ^ @List A@ in elm | ||
| ElmNonEmptyPair !TypeRef -- ^ @NonEmpty A@ represented by @(A, List A)@ in elm | ||
deriving (Show) | ||
|
||
-- | Builtin types defined by core or 3rd party libraries | ||
-- Included definitions: | ||
-- * @Maybe a@ | ||
-- * @Result a b@ | ||
-- * @List a@ | ||
-- * @Time.Posix@ | ||
-- * @Json.Encode.Value@ | ||
data ElmBuiltin = ElmBuiltin | ||
{ builtinImplType :: !Text | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we change the field prefixes to elmBuiltin? The word Impl doesn't look very informative.. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also I find the word "Builtin" a bit misleading. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Impl is leftover from development. I did the change incrementally by porting support from simpler to more complicated types to new structure it will need to be removed.
agree though even this is already improvement over including these things into primitives. The one way in which these things are built in even if they come from 3rd party library (say time which depends on |
||
, builtinImplEncoder :: !Text | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As a user of this API It's not clear from the type what this Text is supposed to be. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should be documented, hover before user will be able to define own things free-rely we need to make it possible to define custom imports for generated modules. So it doesn't make much sense documenting this before that part redesign so whole process could be documented. |
||
, builtinImplDecoder :: !Text | ||
, builtinImplParams :: ![TypeRef] | ||
} deriving (Show) | ||
|
||
-- | Reference to another existing type. | ||
data TypeRef | ||
= RefPrim !ElmPrim | ||
| RefCustom !TypeName | ||
| RefBuiltin !ElmBuiltin | ||
deriving (Show) | ||
|
||
-- | Extracts reference to the existing data type type from some other type elm defintion. | ||
definitionToRef :: ElmDefinition -> TypeRef | ||
definitionToRef = \case | ||
DefRecord ElmRecord{..} -> RefCustom $ TypeName elmRecordName | ||
DefType ElmType{..} -> RefCustom $ TypeName elmTypeName | ||
DefPrim elmPrim -> RefPrim elmPrim | ||
DefType ElmType{..} -> RefCustom $ TypeName elmTypeName | ||
DefPrim elmPrim -> RefPrim elmPrim | ||
DefBuiltin elmBuiltIn -> RefBuiltin elmBuiltIn |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,8 +63,9 @@ import GHC.Generics (C1, Constructor (..), D1, Datatype (..), Generic (..), M1 ( | |
import GHC.TypeLits (ErrorMessage (..), Nat, TypeError) | ||
import GHC.TypeNats (type (+), type (<=?)) | ||
|
||
import Elm.Ast (ElmConstructor (..), ElmDefinition (..), ElmPrim (..), ElmRecord (..), | ||
ElmRecordField (..), ElmType (..), TypeName (..), TypeRef (..), definitionToRef) | ||
import Elm.Ast (ElmBuiltin (..), ElmConstructor (..), ElmDefinition (..), ElmPrim (..), | ||
ElmRecord (..), ElmRecordField (..), ElmType (..), TypeName (..), TypeRef (..), | ||
definitionToRef) | ||
|
||
import qualified Data.Text as T | ||
import qualified Data.Text.Lazy as LT (Text) | ||
|
@@ -118,32 +119,68 @@ instance Elm Double where toElmDefinition _ = DefPrim ElmFloat | |
instance Elm Text where toElmDefinition _ = DefPrim ElmString | ||
instance Elm LT.Text where toElmDefinition _ = DefPrim ElmString | ||
|
||
instance Elm Value where toElmDefinition _ = DefPrim ElmValue | ||
instance (Elm a, Elm b) => Elm (a, b) where | ||
toElmDefinition _ = DefPrim $ ElmPair (elmRef @a) (elmRef @b) | ||
|
||
instance (Elm a, Elm b, Elm c) => Elm (a, b, c) where | ||
toElmDefinition _ = DefPrim $ ElmTriple (elmRef @a) (elmRef @b) (elmRef @c) | ||
|
||
-- TODO: should it be 'Bytes' from @bytes@ package? | ||
-- https://package.elm-lang.org/packages/elm/bytes/latest/Bytes | ||
-- instance Elm B.ByteString where toElmDefinition _ = DefPrim ElmString | ||
-- instance Elm LB.ByteString where toElmDefinition _ = DefPrim ElmString | ||
|
||
instance Elm UTCTime where toElmDefinition _ = DefPrim ElmTime | ||
---------------------------------------------------------------------------- | ||
-- Builtin instances | ||
---------------------------------------------------------------------------- | ||
|
||
instance Elm Value where | ||
toElmDefinition _ = DefBuiltin $ ElmBuiltin | ||
{ builtinImplType = "Value" | ||
, builtinImplEncoder = "Basics.identity" | ||
, builtinImplDecoder = "D.value" | ||
, builtinImplParams = [] | ||
} | ||
|
||
instance Elm UTCTime where | ||
toElmDefinition _ = DefBuiltin $ ElmBuiltin | ||
{ builtinImplType = "Posix" | ||
, builtinImplEncoder = "Iso.encode" | ||
, builtinImplDecoder = "Iso.decoder" | ||
, builtinImplParams = [] | ||
} | ||
|
||
instance Elm a => Elm (Maybe a) where | ||
toElmDefinition _ = DefPrim $ ElmMaybe $ elmRef @a | ||
toElmDefinition _ = DefBuiltin $ ElmBuiltin | ||
{ builtinImplType = "Maybe" | ||
, builtinImplEncoder = "elmStreetEncodeMaybe" | ||
, builtinImplDecoder = "nullable" | ||
, builtinImplParams = [elmRef @a] | ||
} | ||
|
||
instance (Elm a, Elm b) => Elm (Either a b) where | ||
toElmDefinition _ = DefPrim $ ElmResult (elmRef @a) (elmRef @b) | ||
|
||
instance (Elm a, Elm b) => Elm (a, b) where | ||
toElmDefinition _ = DefPrim $ ElmPair (elmRef @a) (elmRef @b) | ||
|
||
instance (Elm a, Elm b, Elm c) => Elm (a, b, c) where | ||
toElmDefinition _ = DefPrim $ ElmTriple (elmRef @a) (elmRef @b) (elmRef @c) | ||
toElmDefinition _ = DefBuiltin $ ElmBuiltin | ||
{ builtinImplType = "Result" | ||
, builtinImplEncoder = "elmStreetEncodeEither" | ||
, builtinImplDecoder = "elmStreetDecodeEither" | ||
, builtinImplParams = [elmRef @a, elmRef @b] | ||
} | ||
|
||
instance Elm a => Elm [a] where | ||
toElmDefinition _ = DefPrim $ ElmList (elmRef @a) | ||
toElmDefinition _ = DefBuiltin $ ElmBuiltin | ||
{ builtinImplType = "List" | ||
, builtinImplEncoder = "E.list" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The E. and D. in this definition seem magical. Where are they coming from?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes. I agreee this is not nice though. But I would probably rather address that in separate PR |
||
, builtinImplDecoder = "D.list" | ||
, builtinImplParams = [elmRef @a] | ||
} | ||
|
||
instance Elm a => Elm (NonEmpty a) where | ||
toElmDefinition _ = DefPrim $ ElmNonEmptyPair (elmRef @a) | ||
toElmDefinition _ = DefBuiltin $ ElmBuiltin | ||
{ builtinImplType = "ElmStreetNonEmptyList" | ||
, builtinImplEncoder = "elmStreetEncodeNonEmpty" | ||
, builtinImplDecoder = "elmStreetDecodeNonEmpty" | ||
, builtinImplParams = [elmRef @a] | ||
} | ||
Comment on lines
+137
to
+183
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. utilize new |
||
|
||
---------------------------------------------------------------------------- | ||
-- Smart constructors | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
related to todo of making implementation less naive