purescript-bridge 0.3.0.6 → 0.3.1.0
raw patch · 8 files changed
+135/−93 lines, 8 files
Files
- README.md +2/−1
- purescript-bridge.cabal +6/−5
- src/Language/PureScript/Bridge.hs +3/−1
- src/Language/PureScript/Bridge/PSTypes.hs +75/−0
- src/Language/PureScript/Bridge/Primitives.hs +16/−57
- src/Language/PureScript/Bridge/Printer.hs +14/−12
- src/Language/PureScript/Bridge/Tuple.hs +7/−17
- src/Language/PureScript/Bridge/TypeInfo.hs +12/−0
README.md view
@@ -1,6 +1,7 @@ # purescript-bridge -Translate your Haskell types to PureScript types.+Translate your Haskell types to PureScript types. It should in theory work for almost all Haskell types, including type constructors!+You just have to instantiate it with dummy parameters from e.g. "Language.PureScript.Bridge.TypeParameters". 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)
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.6+version: 0.3.1.0 -- A short (one-line) description of the package. synopsis: Generate PureScript data types from Haskell data types@@ -53,12 +53,13 @@ library -- Modules exported by the library.- exposed-modules: Language.PureScript.Bridge.SumType- , Language.PureScript.Bridge.TypeInfo- , Language.PureScript.Bridge.Tuple+ exposed-modules: Language.PureScript.Bridge , Language.PureScript.Bridge.Primitives- , Language.PureScript.Bridge , Language.PureScript.Bridge.Printer+ , Language.PureScript.Bridge.PSTypes+ , Language.PureScript.Bridge.SumType+ , Language.PureScript.Bridge.Tuple+ , Language.PureScript.Bridge.TypeInfo , Language.PureScript.Bridge.TypeParameters -- Modules included in this library but not exported.
src/Language/PureScript/Bridge.hs view
@@ -71,7 +71,9 @@ -- | 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+bridgeSumType br (SumType t cs) = SumType fixedT $ map (bridgeConstructor br) cs+ where+ fixedT= t { typeParameters = map fixTypeParameters (typeParameters t)} {--| -- Optimistically and recursively translate types: If the passed TypeBridge returns Nothing,
+ src/Language/PureScript/Bridge/PSTypes.hs view
@@ -0,0 +1,75 @@+{-# LANGUAGE OverloadedStrings #-}+-- | PureScript types to be used for bridges, e.g. in "Language.PureScript.Bridge.Primitives".+module Language.PureScript.Bridge.PSTypes where++import Data.Monoid+import qualified Data.Text as T++import Language.PureScript.Bridge.TypeInfo++-- | Uses type parameters from existing TypeInfo:+psArray :: TypeInfo -> TypeInfo+psArray t = t {+ typePackage = "purescript-prim"+ , typeModule = "Prim"+ , typeName = "Array"+ }++psBool :: TypeInfo+psBool = TypeInfo {+ typePackage = "purescript-prim"+ , typeModule = "Prim"+ , typeName = "Boolean"+ , typeParameters = []+ }++-- | Uses type parameters from existing TypeInfo:+psEither :: TypeInfo -> TypeInfo+psEither t = t {+ typePackage = "purescript-either"+ , typeModule = "Data.Either"+ , typeName = "Either"+ }++psInt :: TypeInfo+psInt = TypeInfo {+ typePackage = "purescript-prim"+ , typeModule = "Prim"+ , typeName = "Int"+ , typeParameters = []+ }++-- | Uses type parameters from existing TypeInfo:+psMaybe :: TypeInfo -> TypeInfo+psMaybe t = t {+ typePackage = "purescript-maybe"+ , typeModule = "Data.Maybe"+ , typeName = "Maybe"+ }+++psString :: TypeInfo+psString = TypeInfo {+ typePackage = "purescript-prim"+ , typeModule = "Prim"+ , typeName = "String"+ , typeParameters = []+ }++-- | Uses type parameters from existing TypeInfo:+psTuple :: TypeInfo -> TypeInfo+psTuple t = t {+ typePackage = "purescript-tuples"+ , typeModule = if size == 2 then "Data.Tuple" else "Data.Tuple.Nested"+ , typeName = "Tuple" <> if size == 2 then "" else T.pack (show size)+ }+ where+ size = length (typeParameters t)++psUnit :: TypeInfo+psUnit = TypeInfo {+ typePackage = "purescript-prelude"+ , typeModule = "Prelude"+ , typeName = "Unit"+ , typeParameters = []+ }
src/Language/PureScript/Bridge/Primitives.hs view
@@ -3,71 +3,30 @@ import Language.PureScript.Bridge.TypeInfo+import Language.PureScript.Bridge.PSTypes -unitBridge :: TypeBridge-unitBridge t- | eqTypeName "()" t = Just $ t {- typePackage = "purescript-prelude"- , typeModule = "Prelude"- , typeName = "Unit"- }- | otherwise = Nothing boolBridge :: TypeBridge-boolBridge t- | eqTypeName "Bool" t = Just $ t {- typePackage = "purescript-prim"- , typeModule = "Prim"- , typeName = "Boolean"- , typeParameters = []- }- | otherwise = Nothing--intBridge :: TypeBridge-intBridge t- | eqTypeName "Int" t = Just $ t {- typePackage = "purescript-prim"- , typeModule = "Prim"- }- | otherwise = Nothing+boolBridge = mkBridgeTo (eqTypeName "Bool") psBool +eitherBridge :: TypeBridge+eitherBridge = mkBridgeTo1 (eqTypeName "Either") psEither -stringBridge :: TypeBridge-stringBridge t- | isStringLike = Just $ t {- typePackage = "purescript-prim"- , typeModule = "Prim"- , typeName = "String"- , typeParameters = []- }- | otherwise = Nothing- where- isStringLike = isText || isString- isText = typeName t == "Text"- isString = typeName t == "[]" && all ((==) "Char" . typeName) (typeParameters t)+intBridge :: TypeBridge+intBridge = mkBridgeTo (eqTypeName "Int") psInt listBridge :: TypeBridge-listBridge t- | eqTypeName "[]" t = Just $ t {- typePackage = "purescript-prim"- , typeModule = "Prim"- , typeName = "Array"- }- | otherwise = Nothing+listBridge = mkBridgeTo1 (eqTypeName "[]") psArray maybeBridge :: TypeBridge-maybeBridge t- | eqTypeName "Maybe" t = Just $ t {- typePackage = "purescript-maybe"- , typeModule = "Data.Maybe"- }- | otherwise = Nothing+maybeBridge = mkBridgeTo1 (eqTypeName "Maybe") psMaybe +stringBridge :: TypeBridge+stringBridge = mkBridgeTo isStringLike psString+ where+ isStringLike t = isText t || isString t+ isText t = typeName t == "Text"+ isString t = typeName t == "[]" && all ((==) "Char" . typeName) (typeParameters t) -eitherBridge :: TypeBridge-eitherBridge t- | eqTypeName "Either" t = Just $ t {- typePackage = "purescript-either"- , typeModule = "Data.Either"- }- | otherwise = Nothing+unitBridge :: TypeBridge+unitBridge = mkBridgeTo (eqTypeName "()") psUnit
src/Language/PureScript/Bridge/Printer.hs view
@@ -66,28 +66,27 @@ sumTypeToText :: SumType -> Text sumTypeToText (SumType t cs) = T.unlines $- "data " <> typeName t <> " ="+ "data " <> typeInfoToText True t <> " =" : [ " " <> T.intercalate "\n | " (map (constructorToText 4) cs) ]- ++ [ "derive instance generic" <> typeName t <> " :: Generic " <> typeName t ]+ ++ [ "\nderive instance generic" <> typeName t <> " :: Generic " <> typeName t ] constructorToText :: Int -> DataConstructor -> Text-constructorToText _ (DataConstructor n (Left ts)) = n <> " " <> T.intercalate " " (map (typeInfoToText needParens) ts) <> "\n"- where needParens = length ts > 1-constructorToText indentation (DataConstructor n (Right rs)) = T.unlines $- n <> " {"- : [ spaces (indentation + 2) <> T.intercalate intercalation (map recordEntryToText rs) ]- ++ [ spaces indentation <> "}" ]+constructorToText _ (DataConstructor n (Left ts)) = n <> " " <> T.intercalate " " (map (typeInfoToText False) ts)+constructorToText indentation (DataConstructor n (Right rs)) =+ n <> " {\n"+ <> spaces (indentation + 2) <> T.intercalate intercalation (map recordEntryToText rs) <> "\n"+ <> spaces indentation <> "}" where intercalation = "\n" <> spaces indentation <> "," <> " " spaces c = T.replicate c " " recordEntryToText :: RecordEntry -> Text-recordEntryToText e = recLabel e <> " :: " <> typeInfoToText False (recValue e)+recordEntryToText e = recLabel e <> " :: " <> typeInfoToText True (recValue e) typeInfoToText :: Bool -> TypeInfo -> Text-typeInfoToText needParens t = if needParens && pLength > 0 then "(" <> inner <> ")" else inner+typeInfoToText topLevel t = if needParens then "(" <> inner <> ")" else inner where inner = typeName t <> if pLength > 0@@ -95,7 +94,8 @@ else "" params = typeParameters t pLength = length params- textParameters = map (typeInfoToText (pLength > 1)) params+ needParens = not topLevel && pLength > 0+ textParameters = map (typeInfoToText False) params sumTypesToModules :: Modules -> [SumType] -> Modules sumTypesToModules = foldr sumTypeToModule@@ -118,7 +118,9 @@ typesToImportLines = foldr typeToImportLines typeToImportLines :: TypeInfo -> ImportLines -> ImportLines-typeToImportLines t = M.alter (Just . updateLine) (typeModule t)+typeToImportLines t = if not (T.null (typeModule t))+ then M.alter (Just . updateLine) (typeModule t)+ else id where updateLine Nothing = ImportLine (typeModule t) (S.singleton (typeName t)) updateLine (Just (ImportLine m types)) = ImportLine m $ S.insert (typeName t) types
src/Language/PureScript/Bridge/Tuple.hs view
@@ -1,29 +1,19 @@ {-# LANGUAGE OverloadedStrings #-} module Language.PureScript.Bridge.Tuple where -import Data.Monoid-import Data.Text (Text) import qualified Data.Text as T - import Language.PureScript.Bridge.TypeInfo--data TupleParserState =- Start | OpenFound | ColonFound | Tuple | NoTuple deriving (Eq, Show)+import Language.PureScript.Bridge.PSTypes (psTuple) tupleBridge :: TypeBridge-tupleBridge t- | isTuple (typeName t) = Just $ t {- typePackage = "purescript-tuples"- , typeModule = if size == 2 then "Data.Tuple" else "Data.Tuple.Nested"- , typeName = "Tuple" <> if size == 2 then "" else T.pack (show size)- }- | otherwise = Nothing- where- size = length $ typeParameters t+tupleBridge = mkBridgeTo1 isTuple psTuple +data TupleParserState =+ Start | OpenFound | ColonFound | Tuple | NoTuple deriving (Eq, Show)+ step :: TupleParserState -> Char -> TupleParserState step Start '(' = OpenFound step Start _ = NoTuple@@ -35,5 +25,5 @@ step Tuple _ = NoTuple step NoTuple _ = NoTuple -isTuple :: Text -> Bool-isTuple = (== Tuple) . T.foldl' step Start+isTuple :: TypeInfo -> Bool+isTuple = (== Tuple) . T.foldl' step Start . typeName
src/Language/PureScript/Bridge/TypeInfo.hs view
@@ -43,3 +43,15 @@ -- | Little helper for type bridge implementers eqTypeName :: Text -> TypeInfo -> Bool eqTypeName name = (== name) . typeName++-- | Helper for simple bridge creation for basic types+mkBridgeTo :: (TypeInfo -> Bool) -> TypeInfo -> TypeBridge+mkBridgeTo match r t+ | match t = Just r+ | otherwise = Nothing++-- | Helper for simple bridge creation for type constructors+mkBridgeTo1 :: (TypeInfo -> Bool) -> (TypeInfo -> TypeInfo) -> TypeBridge+mkBridgeTo1 match r t+ | match t = Just $ r t+ | otherwise = Nothing