module Elm.Type where
import Data.Int (Int16, Int32, Int64, Int8)
import Data.Map
import Data.Proxy
import Data.Text
import Data.Time
import GHC.Generics
import Prelude
data ElmTypeExpr where
TopLevel :: ElmTypeExpr -> ElmTypeExpr
DataType :: Text -> ElmTypeExpr -> ElmTypeExpr
Record :: Text -> ElmTypeExpr -> ElmTypeExpr
Constructor :: Text -> ElmTypeExpr -> ElmTypeExpr
Selector :: Text -> ElmTypeExpr -> ElmTypeExpr
Field :: ElmTypeExpr -> ElmTypeExpr
Sum :: ElmTypeExpr -> ElmTypeExpr -> ElmTypeExpr
Dict :: ElmTypeExpr -> ElmTypeExpr -> ElmTypeExpr
Tuple2 :: ElmTypeExpr -> ElmTypeExpr -> ElmTypeExpr
Product :: ElmTypeExpr -> ElmTypeExpr -> ElmTypeExpr
Unit :: ElmTypeExpr
Primitive :: Text -> ElmTypeExpr
deriving (Eq, Show)
class ElmType a where
toElmType :: a -> ElmTypeExpr
toElmType = genericToElmType . from
default toElmType :: (Generic a, GenericElmType (Rep a)) => a -> ElmTypeExpr
instance ElmType Bool where
toElmType _ = Primitive "Bool"
instance ElmType Char where
toElmType _ = Primitive "Char"
instance ElmType Text where
toElmType _ = Primitive "String"
instance ElmType Float where
toElmType _ = Primitive "Float"
instance ElmType UTCTime where
toElmType _ = Primitive "Date"
instance ElmType Day where
toElmType _ = Primitive "Date"
instance ElmType Double where
toElmType _ = Primitive "Float"
instance ElmType Int where
toElmType _ = Primitive "Int"
instance ElmType Integer where
toElmType _ = Primitive "Int"
instance ElmType Int8 where
toElmType _ = Primitive "Int"
instance ElmType Int16 where
toElmType _ = Primitive "Int"
instance ElmType Int32 where
toElmType _ = Primitive "Int"
instance ElmType Int64 where
toElmType _ = Primitive "Int"
instance (ElmType a, ElmType b) =>
ElmType (a, b) where
toElmType _ =
Tuple2 (toElmType (Proxy :: Proxy a)) (toElmType (Proxy :: Proxy b))
instance ElmType a =>
ElmType [a] where
toElmType _ = Product (Primitive "List") (toElmType (Proxy :: Proxy a))
instance ElmType a =>
ElmType (Maybe a) where
toElmType _ = Product (Primitive "Maybe") (toElmType (Proxy :: Proxy a))
instance (ElmType k, ElmType v) =>
ElmType (Map k v) where
toElmType _ =
Dict (toElmType (Proxy :: Proxy k)) (toElmType (Proxy :: Proxy v))
instance ElmType a =>
ElmType (Proxy a) where
toElmType _ = toElmType (undefined :: a)
class GenericElmType f where
genericToElmType :: f a -> ElmTypeExpr
instance (Datatype d, GenericElmType f) =>
GenericElmType (D1 d f) where
genericToElmType datatype =
DataType
(pack (datatypeName datatype))
(genericToElmType (unM1 datatype))
instance (Constructor c, GenericElmType f) =>
GenericElmType (C1 c f) where
genericToElmType constructor =
if conIsRecord constructor
then Record name body
else Constructor name body
where
name = pack $ conName constructor
body = genericToElmType (unM1 constructor)
instance (Selector c, GenericElmType f) =>
GenericElmType (S1 c f) where
genericToElmType selector =
Selector (pack (selName selector)) (genericToElmType (unM1 selector))
instance GenericElmType U1 where
genericToElmType _ = Unit
instance (ElmType c) =>
GenericElmType (Rec0 c) where
genericToElmType parameter = Field (toElmType (unK1 parameter))
instance (GenericElmType f, GenericElmType g) =>
GenericElmType (f :+: g) where
genericToElmType _ =
Sum
(genericToElmType (undefined :: f p))
(genericToElmType (undefined :: g p))
instance (GenericElmType f, GenericElmType g) =>
GenericElmType (f :*: g) where
genericToElmType _ =
Product
(genericToElmType (undefined :: f p))
(genericToElmType (undefined :: g p))