purescript-bridge 0.3.0.0 → 0.3.0.2
raw patch · 6 files changed
+86/−49 lines, 6 files
Files
- README.md +21/−0
- purescript-bridge.cabal +3/−1
- src/Language/PureScript/Bridge.hs +34/−22
- src/Language/PureScript/Bridge/SumType.hs +10/−8
- src/Language/PureScript/Bridge/TypeInfo.hs +3/−3
- src/Language/PureScript/Bridge/TypeParameters.hs +15/−15
+ README.md view
@@ -0,0 +1,21 @@+# purescript-bridge++Translate your Haskell types to PureScript types.++For compatible JSON representations you should be using [aeson](http://hackage.haskell.org/package/aeson)'s generic encoding/decoding with default options+and `gAesonEncodeJson` and `gAesonDecodeJson` from the [purescript-argonaut-codecs](https://github.com/purescript-contrib/purescript-argonaut-codecs)+package, (Data.Argonaut.Aeson).++At the time of this writing the PR providing `Data.Argonaut.Aeson` was not yet merged.+In the meantime, you can find the PR+[here](https://github.com/purescript-contrib/purescript-argonaut-codecs/pull/12).++Usage of this library is documented in [`Language.Purescript.Bridge`](http://hackage.haskell.org/package/purescript-bridge/docs/Language-PureScript-Bridge.html).++All you should need to get started is: [`writePSTypes`](http://hackage.haskell.org/package/purescript-bridge/docs/Language-PureScript-Bridge.html#writePSTypes).++You can customize data type translation by providing your own `TypeBridge`.++This library is at a really early stage. It works for my use case at the moment and I will fix bugs when they come along.++Expect bugs - especially for more advanced use cases!
purescript-bridge.cabal view
@@ -10,7 +10,7 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 0.3.0.0+version: 0.3.0.2 -- A short (one-line) description of the package. synopsis: Generate PureScript data types from Haskell data types@@ -44,6 +44,8 @@ -- Constraint on the version of Cabal needed to build this package. cabal-version: >=1.10++extra-source-files: README.md source-repository head type: git
src/Language/PureScript/Bridge.hs view
@@ -22,34 +22,40 @@ import Data.Maybe -- | Your entry point to this library and quite likely all you will need.--- | Make sure all your types derive Generic and Typeable.--- | Typeable is not needed from ghc-7.10 on.--- | Then call 'writePSTypes' like this:--- | @--- | let myTypes = [--- | 'toSumType' ('Proxy' :: 'Proxy' MyType1)--- | , 'toSumType' ('Proxy' :: 'Proxy' MyType2)--- | ]--- | 'writePSTypes' 'defaultBridge' "path/to/you/purescript/project" myTypes--- | @--- | You can add new type mappings, like this:--- | @--- | myBridge = 'defaultBridge' <|> mySpecialTypeBridge--- | @--- | Find examples for implementing your own type bridges in: 'Language.PureScript.Bridge.Primitives'--- | A real world use case of this library can be found <https://github.com/gonimo/gonimo-back/blob/master/src/MkFrontendTypes.hs here>.--- | Last but not least:--- | WARNING: This function overwrites files - make backups or use version control!+-- Make sure all your types derive Generic and Typeable.+-- Typeable is not needed from ghc-7.10 on.+--+-- Then call 'writePSTypes' like this:+--+-- > let myTypes = [+-- > 'toSumType' ('Proxy' :: 'Proxy' MyType1)+-- > , 'toSumType' ('Proxy' :: 'Proxy' MyType2)+-- > ]+-- >+-- > 'writePSTypes' 'defaultBridge' "path\/to\/you\/purescript\/project" myTypes+--+-- You can add new type mappings, like this:+-- +--+-- > myBridge = 'defaultBridge' \<|\> mySpecialTypeBridge+-- +--+-- Find examples for implementing your own type bridges in: 'Language.PureScript.Bridge.Primitives'+-- A real world use case of this library can be found <https://github.com/gonimo/gonimo-back/blob/master/src/MkFrontendTypes.hs here>.+-- Last but not least:+--+-- /WARNING/: This function overwrites files - make backups or use version control! writePSTypes :: TypeBridge -> FilePath -> [SumType] -> IO () writePSTypes br root sts = do let bridged = map (bridgeSumType br) sts let modules = M.elems $ sumTypesToModules M.empty bridged mapM_ (printModule root) modules +-- | Translate leaf types in a sum type to match PureScript types. bridgeSumType :: TypeBridge -> SumType -> SumType bridgeSumType br (SumType t cs) = SumType t $ map (bridgeConstructor br) cs -{--+{--| -- Optimistically and recursively translate types: If the passed TypeBridge returns Nothing, -- then the original TypeInfo is returned with the typePackage field cleared. -- You don't need to call this function directly, just use bridgeSumType with your TypeBridge@@ -64,8 +70,12 @@ } -- | Default bridge for mapping primitive/common types:--- | You can append your own bridges like this:--- | defaultBridge <|> myBridge1 <|> myBridge2+-- You can append your own bridges like this:+--+-- > defaultBridge <|> myBridge1 <|> myBridge2+--+-- Find examples for bridge definitions in "Language.PureScript.Bridge.Primitives" and+-- "Language.PureScript.Bridge.Tuple". defaultBridge :: TypeBridge defaultBridge t = stringBridge t <|> listBridge t@@ -75,17 +85,19 @@ <|> intBridge t <|> tupleBridge t +-- | Translate types in a constructor. bridgeConstructor :: TypeBridge -> DataConstructor -> DataConstructor bridgeConstructor br (DataConstructor name (Left infos)) = DataConstructor name . Left $ map (doBridge br) infos bridgeConstructor br (DataConstructor name (Right record)) = DataConstructor name . Right $ map (bridgeRecordEntry br) record +-- | Translate types in a record entry. bridgeRecordEntry :: TypeBridge -> RecordEntry -> RecordEntry bridgeRecordEntry br (RecordEntry label value) = RecordEntry label $ doBridge br value -- | Translate types that come from any module named "Something.TypeParameters" to lower case:--- | Also drop the 1 at the end if present+-- Also drop the 1 at the end if present fixTypeParameters :: TypeInfo -> TypeInfo fixTypeParameters t | T.isSuffixOf "TypeParameters" (typeModule t) = t {
src/Language/PureScript/Bridge/SumType.hs view
@@ -5,9 +5,6 @@ {-# LANGUAGE TypeSynonymInstances #-} -{-# LANGUAGE DeriveGeneric #-}-- module Language.PureScript.Bridge.SumType where import Generics.Deriving@@ -18,8 +15,18 @@ import Language.PureScript.Bridge.TypeInfo +-- | Generic representation of your Haskell types, the contained (leaf) types can be modified to match+-- compatible PureScript types, by using 'TypeBridge' functions like 'defaultBridge' with 'writePSTypes'. data SumType = SumType TypeInfo [DataConstructor] deriving Show +-- | Create a representation of your sum (and product) types,+-- for doing type translations and writing it out to your PureScript modules.+-- In order to get the type information we use a dummy variable of type Proxy (YourType).+toSumType :: forall t. (Generic t, Typeable t, GDataConstructor (Rep t)) => Proxy t -> SumType+toSumType p = SumType (mkTypeInfo p) constructors+ where+ constructors = gToConstructors (from (undefined :: t))+ data DataConstructor = DataConstructor { sigConstructor :: !Text , sigValues :: !(Either [TypeInfo] [RecordEntry])@@ -29,11 +36,6 @@ recLabel :: !Text , recValue :: !TypeInfo } deriving Show--toSumType :: forall t. (Generic t, Typeable t, GDataConstructor (Rep t)) => Proxy t -> SumType-toSumType p = SumType (mkTypeInfo p) constructors- where- constructors = gToConstructors (from (undefined :: t)) class GDataConstructor f where gToConstructors :: f a -> [DataConstructor]
src/Language/PureScript/Bridge/TypeInfo.hs view
@@ -9,11 +9,11 @@ import Data.Typeable --- Translates a Haskell type info to a PureScript type info:+-- | Translates a Haskell type info to a PureScript type info: type TypeBridge = TypeInfo -> Maybe TypeInfo --- Basic info about a data type:+-- | Basic info about a data type: data TypeInfo = TypeInfo { -- | Hackage package typePackage :: !Text@@ -40,6 +40,6 @@ flattenTypeInfo :: TypeInfo -> [TypeInfo] flattenTypeInfo t = t : concatMap flattenTypeInfo (typeParameters t) --- Little helper for type bridge implementers+-- | Little helper for type bridge implementers eqTypeName :: Text -> TypeInfo -> Bool eqTypeName name = (== name) . typeName
src/Language/PureScript/Bridge/TypeParameters.hs view
@@ -1,16 +1,16 @@ -- | As we translate types and not type constructors, we have to pass dummy types--- | to any type constructor. doBridge will translate all parameter types which--- | come from a module TypeParameters (e.g. this one) to lower case.--- | E.g. for translating something like Maybe:--- | @--- | data Maybe' a = Nothing' | Just' a--- | @--- | you would use:--- | @--- | import 'Language.PureScript.Bridge'--- | import 'Language.PureScript.Bridge.TypeParameters'--- | toSumType (Proxy :: Proxy (Maybe A)) -- Note the capital A, which comes from the TypeParameters module.--- | @+-- to any type constructor. doBridge will translate all parameter types which+-- come from a module TypeParameters (e.g. this one) to lower case.+-- E.g. for translating something like Maybe:+-- @+-- data Maybe' a = Nothing' | Just' a+-- @+-- you would use:+-- @+-- import 'Language.PureScript.Bridge'+-- import 'Language.PureScript.Bridge.TypeParameters'+-- toSumType (Proxy :: Proxy (Maybe A)) -- Note the capital A, which comes from the TypeParameters module.+-- @ module Language.PureScript.Bridge.TypeParameters where @@ -43,9 +43,9 @@ data Z -- | You can use those if your type parameters are actually type constructors as well:--- | @--- | toSumType (Proxy :: Proxy ('ReaderT' R M1 A))--- | @+-- @+-- toSumType (Proxy :: Proxy ('ReaderT' R M1 A))+-- @ data A1 a data B1 a data C1 a