module Elm.Type where
import Data.Map
import Data.Proxy
import Data.Text
import Data.Time
import GHC.Generics
import Prelude
data ElmTypeExpr where
TopLevel :: ElmTypeExpr -> ElmTypeExpr
DataType :: String -> ElmTypeExpr -> ElmTypeExpr
Record :: String -> ElmTypeExpr -> ElmTypeExpr
Constructor :: String -> ElmTypeExpr -> ElmTypeExpr
Selector :: String -> ElmTypeExpr -> ElmTypeExpr
Field :: ElmTypeExpr -> ElmTypeExpr
Sum :: ElmTypeExpr -> ElmTypeExpr -> ElmTypeExpr
Dict :: ElmTypeExpr -> ElmTypeExpr -> ElmTypeExpr
Tuple2 :: ElmTypeExpr -> ElmTypeExpr -> ElmTypeExpr
Product :: ElmTypeExpr -> ElmTypeExpr -> ElmTypeExpr
Unit :: ElmTypeExpr
Primitive :: String -> ElmTypeExpr
deriving (Eq, Show)
class ElmType a where
toElmType :: a -> ElmTypeExpr
default toElmType :: (Generic a,GenericElmType (Rep a)) => a -> ElmTypeExpr
toElmType = genericToElmType . from
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 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 (GenericElmType f,Datatype d) => GenericElmType (D1 d f) where
genericToElmType d@(M1 x) =
DataType (datatypeName d)
(genericToElmType x)
instance (Constructor c,GenericElmType f) => GenericElmType (C1 c f) where
genericToElmType c@(M1 x) =
if conIsRecord c
then Record name body
else Constructor name body
where name = conName c
body = genericToElmType x
instance (Selector c,GenericElmType f) => GenericElmType (S1 c f) where
genericToElmType s@(M1 x) =
Selector (selName s)
(genericToElmType x)
instance GenericElmType U1 where
genericToElmType _ = Unit
instance (ElmType c) => GenericElmType (K1 R c) where
genericToElmType (K1 x) = Field (toElmType x)
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))