-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Generate PureScript data types from Haskell data types
--   
--   Generate PureScript data types from Haskell data types
@package purescript-bridge
@version 0.11.0.0


-- | As we translate types and not type constructors, we have to pass dummy
--   types to any type constructor.
--   
--   <tt>buildBridge</tt> will translate all parameter types which come
--   from a module TypeParameters (e.g. this one) to lower case.
--   
--   For translating something like Maybe:
--   
--   <pre>
--   data Maybe' a = Nothing' | Just' a
--   
--   </pre>
--   
--   you would use:
--   
--   <pre>
--   import <a>Language.PureScript.Bridge</a>
--   import <a>Language.PureScript.Bridge.TypeParameters</a>
--   
--   st = mkSumType (<tt>Proxy</tt> :: <tt>Proxy</tt> (Maybe' A)) -- Note that we use "Maybe' A" instead of just Maybe - which would not work.
--   
--   </pre>
module Language.PureScript.Bridge.TypeParameters
data A
data B
data C
data D
data E
data F
data G
data H
data I
data J
data K
data L
data M
data N
data O
data P
data Q
data R
data S
data T
data U
data V
data W
data X
data Y
data Z

-- | You can use those if your type parameters are actually type
--   constructors as well: <tt> st = mkSumType (Proxy :: Proxy
--   (<tt>ReaderT</tt> R M1 A)) </tt>
data A1 a
data B1 a
data C1 a
data D1 a
data E1 a
data F1 a
data G1 a
data H1 a
data I1 a
data J1 a
data K1 a
data L1 a
data M1 a
data N1 a
data O1 a
data P1 a
data Q1 a
data R1 a
data S1 a
data T1 a
data U1 a
data V1 a
data W1 a
data X1 a
data Y1 a
data Z1 a

module Language.PureScript.Bridge.TypeInfo

-- | Basic info about a data type:
data TypeInfo (lang :: Language)
TypeInfo :: !Text -> !Text -> !Text -> ![TypeInfo lang] -> TypeInfo

-- | Hackage package
[_typePackage] :: TypeInfo -> !Text

-- | Full Module path
[_typeModule] :: TypeInfo -> !Text
[_typeName] :: TypeInfo -> !Text
[_typeParameters] :: TypeInfo -> ![TypeInfo lang]

-- | For convenience:
type PSType = TypeInfo PureScript

-- | For convenience:
type HaskellType = TypeInfo Haskell
mkTypeInfo :: Typeable t => Proxy t -> HaskellType
mkTypeInfo' :: TypeRep -> HaskellType
data Language
Haskell :: Language
PureScript :: Language
typePackage :: forall lang_a9gw. Lens' (TypeInfo lang_a9gw) Text
typeModule :: forall lang_a9gw. Lens' (TypeInfo lang_a9gw) Text
typeName :: forall lang_a9gw. Lens' (TypeInfo lang_a9gw) Text
typeParameters :: forall lang_a9gw lang_ad05. Lens (TypeInfo lang_a9gw) (TypeInfo lang_ad05) [TypeInfo lang_a9gw] [TypeInfo lang_ad05]

-- | Types that have a lens for accessing a 'TypeInfo Haskell'.
class HasHaskType t
haskType :: HasHaskType t => Lens' t HaskellType
haskType :: HasHaskType t => Lens' t HaskellType

-- | Put the TypeInfo in a list together with all its
--   <a>_typeParameters</a> (recursively)
flattenTypeInfo :: TypeInfo lang -> [TypeInfo lang]
instance Language.PureScript.Bridge.TypeInfo.HasHaskType Language.PureScript.Bridge.TypeInfo.HaskellType
instance GHC.Show.Show (Language.PureScript.Bridge.TypeInfo.TypeInfo lang)
instance GHC.Classes.Ord (Language.PureScript.Bridge.TypeInfo.TypeInfo lang)
instance GHC.Classes.Eq (Language.PureScript.Bridge.TypeInfo.TypeInfo lang)

module Language.PureScript.Bridge.SumType

-- | Generic representation of your Haskell types.
data SumType (lang :: Language)
SumType :: (TypeInfo lang) -> [DataConstructor lang] -> SumType

-- | 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
--   <a>Proxy</a> (YourType).
mkSumType :: forall t. (Generic t, Typeable t, GDataConstructor (Rep t)) => Proxy t -> SumType Haskell
data DataConstructor (lang :: Language)
DataConstructor :: !Text -> !(Either [TypeInfo lang] [RecordEntry lang]) -> DataConstructor

-- | e.g. <a>Left</a>/<a>Right</a> for <a>Either</a>
[_sigConstructor] :: DataConstructor -> !Text
[_sigValues] :: DataConstructor -> !(Either [TypeInfo lang] [RecordEntry lang])
data RecordEntry (lang :: Language)
RecordEntry :: !Text -> !(TypeInfo lang) -> RecordEntry

-- | e.g. <tt>runState</tt> for <tt>State</tt>
[_recLabel] :: RecordEntry -> !Text
[_recValue] :: RecordEntry -> !(TypeInfo lang)

-- | Get all used types in a sum type.
--   
--   This includes all types found at the right hand side of a sum type
--   definition, not the type parameters of the sum type itself
getUsedTypes :: SumType lang -> Set (TypeInfo lang)
constructorToTypes :: DataConstructor lang -> Set (TypeInfo lang) -> Set (TypeInfo lang)
sigConstructor :: forall lang_alyY. Lens' (DataConstructor lang_alyY) Text
sigValues :: forall lang_alyY lang_anhc. Lens (DataConstructor lang_alyY) (DataConstructor lang_anhc) (Either [TypeInfo lang_alyY] [RecordEntry lang_alyY]) (Either [TypeInfo lang_anhc] [RecordEntry lang_anhc])

-- | TypInfo lens for <a>SumType</a>.
sumTypeInfo :: Functor f => (TypeInfo lang -> f (TypeInfo lang)) -> SumType lang -> f (SumType lang)

-- | DataConstructor lens for <a>SumType</a>.
sumTypeConstructors :: Functor f => ([DataConstructor lang] -> f [DataConstructor lang]) -> SumType lang -> f (SumType lang)
recLabel :: forall lang_alyX. Lens' (RecordEntry lang_alyX) Text
recValue :: forall lang_alyX lang_anig. Lens (RecordEntry lang_alyX) (RecordEntry lang_anig) (TypeInfo lang_alyX) (TypeInfo lang_anig)
instance GHC.Classes.Eq (Language.PureScript.Bridge.SumType.SumType lang)
instance GHC.Show.Show (Language.PureScript.Bridge.SumType.SumType lang)
instance GHC.Classes.Eq (Language.PureScript.Bridge.SumType.DataConstructor lang)
instance GHC.Show.Show (Language.PureScript.Bridge.SumType.DataConstructor lang)
instance GHC.Classes.Eq (Language.PureScript.Bridge.SumType.RecordEntry lang)
instance GHC.Show.Show (Language.PureScript.Bridge.SumType.RecordEntry lang)
instance (GHC.Generics.Datatype a, Language.PureScript.Bridge.SumType.GDataConstructor c) => Language.PureScript.Bridge.SumType.GDataConstructor (GHC.Generics.D1 a c)
instance (Language.PureScript.Bridge.SumType.GDataConstructor a, Language.PureScript.Bridge.SumType.GDataConstructor b) => Language.PureScript.Bridge.SumType.GDataConstructor (a GHC.Generics.:+: b)
instance (GHC.Generics.Constructor a, Language.PureScript.Bridge.SumType.GRecordEntry b) => Language.PureScript.Bridge.SumType.GDataConstructor (GHC.Generics.C1 a b)
instance (Language.PureScript.Bridge.SumType.GRecordEntry a, Language.PureScript.Bridge.SumType.GRecordEntry b) => Language.PureScript.Bridge.SumType.GRecordEntry (a GHC.Generics.:*: b)
instance Language.PureScript.Bridge.SumType.GRecordEntry GHC.Generics.U1
instance (GHC.Generics.Selector a, Data.Typeable.Internal.Typeable t) => Language.PureScript.Bridge.SumType.GRecordEntry (GHC.Generics.S1 a (GHC.Generics.K1 GHC.Generics.R t))

module Language.PureScript.Bridge.Printer
data Module (lang :: Language)
PSModule :: !Text -> !(Map Text ImportLine) -> ![SumType lang] -> Module
[psModuleName] :: Module -> !Text
[psImportLines] :: Module -> !(Map Text ImportLine)
[psTypes] :: Module -> ![SumType lang]
type PSModule = Module PureScript
data ImportLine
ImportLine :: !Text -> !(Set Text) -> ImportLine
[importModule] :: ImportLine -> !Text
[importTypes] :: ImportLine -> !(Set Text)
type Modules = Map Text PSModule
type ImportLines = Map Text ImportLine
printModule :: FilePath -> PSModule -> IO ()
sumTypesToNeededPackages :: [SumType lang] -> Set Text
sumTypeToNeededPackages :: SumType lang -> Set Text
moduleToText :: Module PureScript -> Text
_lensImports :: [ImportLine]
importLineToText :: ImportLine -> Text
sumTypeToText :: SumType PureScript -> Text
sumTypeToTypeDecls :: SumType PureScript -> Text
sumTypeToPrismsAndLenses :: SumType PureScript -> Text
sumTypeToPrisms :: SumType PureScript -> Text
sumTypeToLenses :: SumType PureScript -> Text
constructorToText :: Int -> DataConstructor PureScript -> Text
spaces :: Int -> Text
typeNameAndForall :: SumType PureScript -> (Text, Text)
fromEntries :: (RecordEntry a -> Text) -> [RecordEntry a] -> Text
mkFnArgs :: [RecordEntry PureScript] -> Text
mkTypeSig :: [RecordEntry PureScript] -> Text
constructorToPrism :: Bool -> SumType PureScript -> DataConstructor PureScript -> Text
recordEntryToLens :: SumType PureScript -> Text -> RecordEntry PureScript -> Text
recordEntryToText :: RecordEntry PureScript -> Text
typeInfoToText :: Bool -> PSType -> Text
sumTypesToModules :: Modules -> [SumType PureScript] -> Modules
sumTypeToModule :: SumType PureScript -> Modules -> Modules
typesToImportLines :: ImportLines -> Set PSType -> ImportLines
typeToImportLines :: PSType -> ImportLines -> ImportLines
importsFromList :: [ImportLine] -> Map Text ImportLine
mergeImportLines :: ImportLines -> ImportLines -> ImportLines
unlessM :: Monad m => m Bool -> m () -> m ()
instance GHC.Show.Show (Language.PureScript.Bridge.Printer.Module lang)
instance GHC.Show.Show Language.PureScript.Bridge.Printer.ImportLine


-- | A bridge builder DSL, powered by <a>Monad</a>, <a>Alternative</a> and
--   lens.
--   
--   Bridges can be built within the <a>BridgeBuilder</a> monad. You can
--   check properties of the to-be-bridged <a>HaskellType</a> with
--   <a>^==</a> or <a>doCheck</a>, you have choice (<a>&lt;|&gt;</a>), you
--   can fail (<a>empty</a>) and you can return a translated <a>PSType</a>
--   (<a>return</a>). The <a>HaskellType</a> can be accessed with:
--   
--   <pre>
--   view haskType
--   </pre>
--   
--   Find usage examples in <a>Language.PureScript.Bridge.Primitives</a>
--   and <a>Language.PureScript.Bridge.PSTypes</a>
module Language.PureScript.Bridge.Builder
data BridgeBuilder a
type BridgePart = BridgeBuilder PSType

-- | Bridges to use when a <a>BridgePart</a> returns <a>Nothing</a> (See
--   <a>buildBridgeWithCustomFixUp</a>).
--   
--   It is similar to BridgeBuilder but does not offer choice or failure.
--   It is used for constructing fallbacks if a <a>BridgePart</a> evaluates
--   to <a>Nothing</a>.
--   
--   For type definitions you should use the more generic
--   (<a>MonadReader</a> <a>BridgeData</a> m) constraint. This way your
--   code will work in both <a>FixUpBuilder</a> and <a>BridgeBuilder</a>:
--   
--   <pre>
--   {-# LANGUAGE FlexibleContexts #-}
--   
--   import           Control.Monad.Reader.Class
--   import           Language.PureScript.Bridge.TypeInfo
--   </pre>
data FixUpBuilder a
type FixUpBridge = FixUpBuilder PSType
data BridgeData

-- | Lens for access to the complete bridge from within our Reader monad.
--   
--   This is used for example for implementing <a>psTypeParameters</a>.
fullBridge :: Lens' BridgeData FullBridge

-- | Check parts of <a>haskType</a> for equality:
--   
--   <pre>
--   textBridge :: BridgePart
--   textBridge = do
--     typeName ^== "Text"
--     typeModule ^== "Data.Text.Internal" &lt;|&gt; typeModule ^== "Data.Text.Internal.Lazy"
--     return psString
--   </pre>
(^==) :: Eq a => Getter HaskellType a -> a -> BridgeBuilder ()
infix 4 ^==

-- | Do some check on properties of <a>haskType</a>.
doCheck :: Getter HaskellType a -> (a -> Bool) -> BridgeBuilder ()

-- | An associative binary operation
(<|>) :: Alternative f => forall a. f a -> f a -> f a

-- | Bridge <a>haskType</a> <a>typeParameters</a> over to PureScript types.
--   
--   To be used for bridging type constructors.
psTypeParameters :: MonadReader BridgeData m => m [PSType]
type FullBridge = HaskellType -> PSType

-- | Build a bridge.
--   
--   This is a convenience wrapper for <a>buildBridgeWithCustomFixUp</a>
--   and should normally be sufficient.
--   
--   Definition:
--   
--   <pre>
--   buildBridgeWithCustomFixUp clearPackageFixUp
--   </pre>
buildBridge :: BridgePart -> FullBridge

-- | Bridge to PureScript by simply clearing out the <a>_typePackage</a>
--   field. This bridge is used by default as <a>FixUpBridge</a> by
--   <a>buildBridge</a>:
--   
--   <pre>
--   buildBridge = buildBridgeWithCustomFixUp clearPackageFixUp
--   </pre>
--   
--   Thus, if no bridge matches a type, it gets optimistically translated
--   to a PureScript type which is idential to the Haskell type. Only the
--   <a>_typePackage</a> field gets cleared, as it is very unlikely that
--   the PureScript package is called the same as the Haskell package.
--   
--   Alternatively, if you are not that optimistic, you can use errorFixUp
--   - which simply calls <a>error</a> when used.
--   
--   <pre>
--   buildBridgeWithCustomFixUp errorFixUp yourBridge
--   </pre>
--   
--   Of course you can also write your own <a>FixUpBridge</a>. It works the
--   same as for <a>BridgePart</a>, but you can not have choice
--   (<a>&lt;|&gt;</a>) or failure (<a>empty</a>).
clearPackageFixUp :: MonadReader BridgeData m => m PSType

-- | A <a>FixUpBridge</a> which calles <a>error</a> when used. Usage:
--   
--   <pre>
--   buildBridgeWithCustomFixUp errorFixUp yourBridge
--   </pre>
errorFixUp :: MonadReader BridgeData m => m PSType

-- | Takes a constructed BridgePart and makes it a total function
--   (<a>FullBridge</a>) by using the supplied <a>FixUpBridge</a> when
--   <a>BridgePart</a> returns <a>Nothing</a>.
buildBridgeWithCustomFixUp :: FixUpBridge -> BridgePart -> FullBridge
instance Control.Monad.Reader.Class.MonadReader Language.PureScript.Bridge.Builder.BridgeData Language.PureScript.Bridge.Builder.BridgeBuilder
instance GHC.Base.Monad Language.PureScript.Bridge.Builder.BridgeBuilder
instance GHC.Base.Applicative Language.PureScript.Bridge.Builder.BridgeBuilder
instance GHC.Base.Functor Language.PureScript.Bridge.Builder.BridgeBuilder
instance Control.Monad.Reader.Class.MonadReader Language.PureScript.Bridge.Builder.BridgeData Language.PureScript.Bridge.Builder.FixUpBuilder
instance GHC.Base.Monad Language.PureScript.Bridge.Builder.FixUpBuilder
instance GHC.Base.Applicative Language.PureScript.Bridge.Builder.FixUpBuilder
instance GHC.Base.Functor Language.PureScript.Bridge.Builder.FixUpBuilder
instance Language.PureScript.Bridge.TypeInfo.HasHaskType Language.PureScript.Bridge.Builder.BridgeData
instance GHC.Base.Alternative Language.PureScript.Bridge.Builder.BridgeBuilder
instance GHC.Base.MonadPlus Language.PureScript.Bridge.Builder.BridgeBuilder


-- | PureScript types to be used for bridges, e.g. in
--   <a>Language.PureScript.Bridge.Primitives</a>.
module Language.PureScript.Bridge.PSTypes

-- | Uses type parameters from <a>haskType</a> (bridged).
psArray :: MonadReader BridgeData m => m PSType
psBool :: PSType

-- | Uses type parameters from <a>haskType</a> (bridged).
psEither :: MonadReader BridgeData m => m PSType
psInt :: PSType
psNumber :: PSType

-- | Uses type parameters from <a>haskType</a> (bridged).
psMaybe :: MonadReader BridgeData m => m PSType
psString :: PSType

-- | Uses type parameters from <a>haskType</a> (bridged).
psTuple :: MonadReader BridgeData m => m PSType
psUnit :: PSType

module Language.PureScript.Bridge.Primitives
boolBridge :: BridgePart
eitherBridge :: BridgePart

-- | Dummy bridge, translates every type with <a>clearPackageFixUp</a>
dummyBridge :: MonadReader BridgeData m => m PSType
intBridge :: BridgePart
doubleBridge :: BridgePart
listBridge :: BridgePart
maybeBridge :: BridgePart
stringBridge :: BridgePart
textBridge :: BridgePart
unitBridge :: BridgePart

module Language.PureScript.Bridge.Tuple
tupleBridge :: BridgePart
data TupleParserState
Start :: TupleParserState
OpenFound :: TupleParserState
ColonFound :: TupleParserState
Tuple :: TupleParserState
NoTuple :: TupleParserState
step :: TupleParserState -> Char -> TupleParserState
isTuple :: HaskellType -> Bool
instance GHC.Show.Show Language.PureScript.Bridge.Tuple.TupleParserState
instance GHC.Classes.Eq Language.PureScript.Bridge.Tuple.TupleParserState

module Language.PureScript.Bridge

-- | Translate all <a>TypeInfo</a> values in a <a>SumType</a> to PureScript
--   types.
--   
--   Example usage, with defaultBridge:
--   
--   <pre>
--   data Foo = Foo | Bar Int | FooBar Int Text deriving (Generic, Typeable, Show)
--   </pre>
--   
--   <pre>
--   bridgeSumType (buildBridge defaultBridge) (mkSumType (Proxy :: Proxy Foo))
--   </pre>
bridgeSumType :: FullBridge -> SumType Haskell -> SumType PureScript

-- | Default bridge for mapping primitive/common types: You can append your
--   own bridges like this:
--   
--   <pre>
--   defaultBridge &lt;|&gt; myBridge1 &lt;|&gt; myBridge2
--   </pre>
--   
--   Find examples for bridge definitions in
--   <a>Language.PureScript.Bridge.Primitives</a> and
--   <a>Language.PureScript.Bridge.Tuple</a>.
defaultBridge :: BridgePart

-- | 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 list all your types you want to use in PureScript and call
--   <a>writePSTypes</a>:
--   
--   <pre>
--   let myTypes = [
--       mkSumType (Proxy :: Proxy MyType1)
--     , mkSumType (Proxy :: Proxy MyType2)
--    ]
--   
--   writePSTypes "path/to/your/purescript/project" (buildBridge defaultBridge) myTypes
--   </pre>
--   
--   You can define your own type bridges based on <a>defaultBridge</a>:
--   
--   <pre>
--   myBridge = defaultBridge &lt;|&gt; mySpecialTypeBridge
--   </pre>
--   
--   and use it with <a>writePSTypes</a>:
--   
--   <pre>
--   writePSTypes "path/to/your/purescript/project" (buildBridge myBridge) myTypes
--   </pre>
--   
--   Find examples for implementing your own bridges in:
--   <a>Language.PureScript.Bridge.Primitives</a>.
--   
--   <h2>Result:</h2>
--   
--   <a>writePSTypes</a> will write out PureScript modules to the given
--   path, mirroring the hierarchy of the Haskell modules the types came
--   from. In addition a list of needed PS packages is printed to the
--   console.
--   
--   The list of needed packages is retrieved from the bridged
--   <a>TypeInfo</a> data, so make sure you set <a>_typePackage</a>
--   correctly in your own bridges, in order for this feature to be useful.
--   
--   <h2>Real world usage example (at time of this writing outdated, at
--   time of reading hopefully fixed):</h2>
--   
--   A real world use case of this library can be found <a>here</a>.
--   
--   With custom bridges defined <a>here</a> and custom PS types defined
--   <a>here</a>.
--   
--   Parts of the generated output can be found <a>here</a>.
--   
--   Note how <tt>Secret</tt> and <tt>Key</tt> get translated according to
--   our custom rules, with correct imports and everything. Also the
--   formatting is quite nice, would you have guessed that this code was
--   generated?
--   
--   <h2><i>WARNING</i>:</h2>
--   
--   This function overwrites files - make backups or use version control!
writePSTypes :: FilePath -> FullBridge -> [SumType Haskell] -> IO ()
