language-thrift 0.11.0.0 → 0.12.0.0
raw patch · 3 files changed
+115/−109 lines, 3 filesdep −hspec-discoverdep ~megaparsecdep ~semigroupsnew-uploaderPVP ok
version bump matches the API change (PVP)
Dependencies removed: hspec-discover
Dependency ranges changed: megaparsec, semigroups
API changes (from Hackage documentation)
- Language.Thrift.Parser: constant :: (Stream s, Token s ~ Char) => Parser s (Const SourcePos)
+ Language.Thrift.Parser: constant :: (TraversableStream s, Token s ~ Char) => Parser s (Const SourcePos)
- Language.Thrift.Parser: constantValue :: (Stream s, Token s ~ Char) => Parser s (ConstValue SourcePos)
+ Language.Thrift.Parser: constantValue :: (TraversableStream s, Token s ~ Char) => Parser s (ConstValue SourcePos)
- Language.Thrift.Parser: definition :: (Stream s, Token s ~ Char) => Parser s (Definition SourcePos)
+ Language.Thrift.Parser: definition :: (TraversableStream s, Token s ~ Char) => Parser s (Definition SourcePos)
- Language.Thrift.Parser: docstring :: (Stream s, Token s ~ Char) => Parser s Text
+ Language.Thrift.Parser: docstring :: (TraversableStream s, Token s ~ Char) => Parser s Text
- Language.Thrift.Parser: enum :: (Stream s, Token s ~ Char) => Parser s (Enum SourcePos)
+ Language.Thrift.Parser: enum :: (TraversableStream s, Token s ~ Char) => Parser s (Enum SourcePos)
- Language.Thrift.Parser: exception :: (Stream s, Token s ~ Char) => Parser s (Struct SourcePos)
+ Language.Thrift.Parser: exception :: (TraversableStream s, Token s ~ Char) => Parser s (Struct SourcePos)
- Language.Thrift.Parser: header :: (Stream s, Token s ~ Char) => Parser s (Header SourcePos)
+ Language.Thrift.Parser: header :: (TraversableStream s, Token s ~ Char) => Parser s (Header SourcePos)
- Language.Thrift.Parser: include :: (Stream s, Token s ~ Char) => Parser s (Include SourcePos)
+ Language.Thrift.Parser: include :: (TraversableStream s, Token s ~ Char) => Parser s (Include SourcePos)
- Language.Thrift.Parser: namespace :: (Stream s, Token s ~ Char) => Parser s (Namespace SourcePos)
+ Language.Thrift.Parser: namespace :: (TraversableStream s, Token s ~ Char) => Parser s (Namespace SourcePos)
- Language.Thrift.Parser: parse :: (Stream s, Token s ~ Char) => FilePath -> s -> Either (ParseErrorBundle s Void) (Program SourcePos)
+ Language.Thrift.Parser: parse :: (TraversableStream s, Token s ~ Char) => FilePath -> s -> Either (ParseErrorBundle s Void) (Program SourcePos)
- Language.Thrift.Parser: program :: (Stream s, Token s ~ Char) => Parser s (Program SourcePos)
+ Language.Thrift.Parser: program :: (TraversableStream s, Token s ~ Char) => Parser s (Program SourcePos)
- Language.Thrift.Parser: senum :: (Stream s, Token s ~ Char) => Parser s (Senum SourcePos)
+ Language.Thrift.Parser: senum :: (TraversableStream s, Token s ~ Char) => Parser s (Senum SourcePos)
- Language.Thrift.Parser: service :: (Stream s, Token s ~ Char) => Parser s (Service SourcePos)
+ Language.Thrift.Parser: service :: (TraversableStream s, Token s ~ Char) => Parser s (Service SourcePos)
- Language.Thrift.Parser: struct :: (Stream s, Token s ~ Char) => Parser s (Struct SourcePos)
+ Language.Thrift.Parser: struct :: (TraversableStream s, Token s ~ Char) => Parser s (Struct SourcePos)
- Language.Thrift.Parser: thriftIDL :: (Stream s, Token s ~ Char) => Parsec Void s (Program SourcePos)
+ Language.Thrift.Parser: thriftIDL :: (TraversableStream s, Token s ~ Char) => Parsec Void s (Program SourcePos)
- Language.Thrift.Parser: typeDefinition :: (Stream s, Token s ~ Char) => Parser s (Type SourcePos)
+ Language.Thrift.Parser: typeDefinition :: (TraversableStream s, Token s ~ Char) => Parser s (Type SourcePos)
- Language.Thrift.Parser: typeReference :: (Stream s, Token s ~ Char) => Parser s (TypeReference SourcePos)
+ Language.Thrift.Parser: typeReference :: (TraversableStream s, Token s ~ Char) => Parser s (TypeReference SourcePos)
- Language.Thrift.Parser: typedef :: (Stream s, Token s ~ Char) => Parser s (Typedef SourcePos)
+ Language.Thrift.Parser: typedef :: (TraversableStream s, Token s ~ Char) => Parser s (Typedef SourcePos)
- Language.Thrift.Parser: union :: (Stream s, Token s ~ Char) => Parser s (Struct SourcePos)
+ Language.Thrift.Parser: union :: (TraversableStream s, Token s ~ Char) => Parser s (Struct SourcePos)
- Language.Thrift.Parser: whiteSpace :: (Stream s, Token s ~ Char) => Parser s ()
+ Language.Thrift.Parser: whiteSpace :: (TraversableStream s, Token s ~ Char) => Parser s ()
Files
- CHANGES.md +5/−0
- language-thrift.cabal +67/−66
- src/Language/Thrift/Parser.hs +43/−43
CHANGES.md view
@@ -1,3 +1,8 @@+0.12.0.0 (2020-12-31)+=====================++- Port to Megaparsec 9.+ 0.11.0.0 (2019-10-01) =====================
language-thrift.cabal view
@@ -1,24 +1,24 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.31.2.+-- This file has been generated from package.yaml by hpack version 0.34.2. -- -- see: https://github.com/sol/hpack ----- hash: 4e717e225f20a4779ba92b55f6212040c7138271b8a10c8e4e0d5a62351472a9+-- hash: d80a1a764a9011be77762ba5390e28715af67b898b56b31e76b9845e55684958 name: language-thrift-version: 0.11.0.0-bug-reports: https://github.com/abhinav/language-thrift/issues-build-type: Simple-license: BSD3-license-file: LICENSE-maintainer: Abhinav Gupta <mail@abhinavg.net>-homepage: https://github.com/abhinav/language-thrift#readme+version: 0.12.0.0 synopsis: Parser and pretty printer for the Thrift IDL format. description: This package provides a parser and pretty printer for the <http://thrift.apache.org/docs/idl Thrift IDL format>. category: Language+homepage: https://github.com/abhinav/language-thrift#readme+bug-reports: https://github.com/abhinav/language-thrift/issues author: Abhinav Gupta+maintainer: Abhinav Gupta <mail@abhinavg.net>+license: BSD3+license-file: LICENSE+build-type: Simple extra-source-files: CHANGES.md examples/generateHaskellTypes.hs@@ -28,64 +28,65 @@ test/data/docstring-2.txt source-repository head- type: git- location: https://github.com/abhinav/language-thrift+ type: git+ location: https://github.com/abhinav/language-thrift library- hs-source-dirs:- src- ghc-options: -Wall- build-depends:- ansi-wl-pprint >=0.6 && <0.7,- base >=4.7 && <5,- containers >=0.5 && <0.7,- megaparsec >=7.0 && <8.0,- scientific >=0.3 && <0.4,- semigroups >=0.18 && <0.19,- text >=1.2,- transformers- exposed-modules:- Language.Thrift.AST- Language.Thrift.Parser- Language.Thrift.Pretty- other-modules:- Language.Thrift.Internal.AST- Language.Thrift.Internal.Lens- Language.Thrift.Internal.Reserved- Paths_language_thrift- default-language: Haskell2010+ exposed-modules:+ Language.Thrift.AST+ Language.Thrift.Parser+ Language.Thrift.Pretty+ other-modules:+ Language.Thrift.Internal.AST+ Language.Thrift.Internal.Lens+ Language.Thrift.Internal.Reserved+ Paths_language_thrift+ hs-source-dirs:+ src+ ghc-options: -Wall+ build-depends:+ ansi-wl-pprint >=0.6 && <0.7+ , base >=4.7 && <5+ , containers >=0.5 && <0.7+ , megaparsec >=9.0 && <10.0+ , scientific >=0.3 && <0.4+ , semigroups >=0.18 && <0.20+ , text >=1.2+ , transformers+ default-language: Haskell2010 test-suite spec- type: exitcode-stdio-1.0- main-is: Main.hs- hs-source-dirs:- src- test- ghc-options: -Wall- build-depends:- QuickCheck >=2.5,- ansi-wl-pprint >=0.6 && <0.7,- base >=4.7 && <5,- containers >=0.5 && <0.7,- hspec >=2.0,- hspec-discover >=2.1,- language-thrift,- megaparsec >=7.0 && <8.0,- scientific >=0.3 && <0.4,- semigroups >=0.18 && <0.19,- text >=1.2,- transformers- other-modules:- Language.Thrift.AST- Language.Thrift.Internal.AST- Language.Thrift.Internal.Lens- Language.Thrift.Internal.Reserved- Language.Thrift.Parser- Language.Thrift.Pretty- Language.Thrift.Arbitrary- Language.Thrift.ASTSpec- Language.Thrift.ParserSpec- Spec- TestUtils- Paths_language_thrift- default-language: Haskell2010+ type: exitcode-stdio-1.0+ main-is: Main.hs+ hs-source-dirs:+ src+ test+ ghc-options: -Wall+ build-tool-depends:+ hspec-discover:hspec-discover >=2.1+ build-depends:+ QuickCheck >=2.5+ , ansi-wl-pprint >=0.6 && <0.7+ , base >=4.7 && <5+ , containers >=0.5 && <0.7+ , hspec >=2.0+ , language-thrift+ , megaparsec >=9.0 && <10.0+ , scientific >=0.3 && <0.4+ , semigroups >=0.18 && <0.20+ , text >=1.2+ , transformers+ other-modules:+ Language.Thrift.AST+ Language.Thrift.Internal.AST+ Language.Thrift.Internal.Lens+ Language.Thrift.Internal.Reserved+ Language.Thrift.Parser+ Language.Thrift.Pretty+ Language.Thrift.Arbitrary+ Language.Thrift.ASTSpec+ Language.Thrift.ParserSpec+ Spec+ TestUtils+ Paths_language_thrift+ default-language: Haskell2010
src/Language/Thrift/Parser.hs view
@@ -107,14 +107,14 @@ -- | @parse name contents@ parses the contents of a Thrift document with name -- @name@ held in @contents@. parse- :: (P.Stream s, P.Token s ~ Char)+ :: (P.TraversableStream s, P.Token s ~ Char) => FilePath -> s -> Either (P.ParseErrorBundle s Void) (T.Program P.SourcePos) parse = P.parse thriftIDL -- | Megaparsec parser that is able to parse full Thrift documents. thriftIDL- :: (P.Stream s, P.Token s ~ Char)+ :: (P.TraversableStream s, P.Token s ~ Char) => P.Parsec Void s (T.Program P.SourcePos) thriftIDL = runParser program @@ -131,11 +131,11 @@ return s -- | Optional whitespace.-whiteSpace :: (P.Stream s, P.Token s ~ Char) => Parser s ()+whiteSpace :: (P.TraversableStream s, P.Token s ~ Char) => Parser s () whiteSpace = someSpace <|> pure () -- | Required whitespace.-someSpace :: (P.Stream s, P.Token s ~ Char) => Parser s ()+someSpace :: (P.TraversableStream s, P.Token s ~ Char) => Parser s () someSpace = P.skipSome $ readDocstring <|> skipComments <|> skipSpace where readDocstring = do@@ -194,7 +194,7 @@ -- This parses attempts to preserve indentation inside the docstring while -- getting rid of the aligned @*@s (if any) and any other preceding space. ---docstring :: (P.Stream s, P.Token s ~ Char) => Parser s Text+docstring :: (P.TraversableStream s, P.Token s ~ Char) => Parser s Text docstring = do P.try (string "/**") >> P.skipMany hspace indent <- fromIntegral . P.unPos <$> PL.indentLevel@@ -242,20 +242,20 @@ loop True maxDedent (line:chunks) -symbolic :: forall s. (P.Stream s, P.Token s ~ Char) => Char -> Parser s ()+symbolic :: forall s. (P.TraversableStream s, P.Token s ~ Char) => Char -> Parser s () symbolic c = void $ PL.symbol whiteSpace (P.tokenToChunk (Proxy :: Proxy s) c) -token :: (P.Stream s, P.Token s ~ Char) => Parser s a -> Parser s a+token :: (P.TraversableStream s, P.Token s ~ Char) => Parser s a -> Parser s a token = PL.lexeme whiteSpace braces, angles, parens- :: (P.Stream s, P.Token s ~ Char) => Parser s a -> Parser s a+ :: (P.TraversableStream s, P.Token s ~ Char) => Parser s a -> Parser s a braces = P.between (symbolic '{') (symbolic '}') angles = P.between (symbolic '<') (symbolic '>') parens = P.between (symbolic '(') (symbolic ')') -comma, semi, colon, equals :: (P.Stream s, P.Token s ~ Char) => Parser s ()+comma, semi, colon, equals :: (P.TraversableStream s, P.Token s ~ Char) => Parser s () comma = symbolic ',' semi = symbolic ';'@@ -271,7 +271,7 @@ -- | Parses a reserved identifier and adds it to the collection of known -- reserved keywords.-reserved :: (P.Stream s, P.Token s ~ Char) => String -> Parser s ()+reserved :: (P.TraversableStream s, P.Token s ~ Char) => String -> Parser s () reserved name = errorUnlessReserved name >> P.label name $ token $ P.try $ do@@ -280,7 +280,7 @@ -- | A string literal. @"hello"@-literal :: (P.Stream s, P.Token s ~ Char) => Parser s Text+literal :: (P.TraversableStream s, P.Token s ~ Char) => Parser s Text literal = P.label "string literal" $ token $ stringLiteral '"' <|> stringLiteral '\'' @@ -289,12 +289,12 @@ PC.char q >> P.manyTill PL.charLiteral (PC.char q) -integer :: (P.Stream s, P.Token s ~ Char) => Parser s Integer+integer :: (P.TraversableStream s, P.Token s ~ Char) => Parser s Integer integer = token PL.decimal -- | An identifier in a Thrift file.-identifier :: (P.Stream s, P.Token s ~ Char) => Parser s Text+identifier :: (P.TraversableStream s, P.Token s ~ Char) => Parser s Text identifier = P.label "identifier" $ token $ do name <- (:) <$> (PC.letterChar <|> PC.char '_')@@ -305,7 +305,7 @@ -- | Top-level parser to parse complete Thrift documents.-program :: (P.Stream s, P.Token s ~ Char) => Parser s (T.Program P.SourcePos)+program :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.Program P.SourcePos) program = whiteSpace >> T.Program <$> many (header <* optionalSep)@@ -313,7 +313,7 @@ <* P.eof -- | Headers defined for the IDL.-header :: (P.Stream s, P.Token s ~ Char) => Parser s (T.Header P.SourcePos)+header :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.Header P.SourcePos) header = P.choice [ T.HeaderInclude <$> include , T.HeaderNamespace <$> namespace@@ -326,7 +326,7 @@ -- > -- > typedef common.Foo Bar ---include :: (P.Stream s, P.Token s ~ Char) => Parser s (T.Include P.SourcePos)+include :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.Include P.SourcePos) include = reserved "include" >> withPosition (T.Include <$> literal) @@ -335,7 +335,7 @@ -- -- > namespace py my_service.generated namespace- :: (P.Stream s, P.Token s ~ Char) => Parser s (T.Namespace P.SourcePos)+ :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.Namespace P.SourcePos) namespace = P.choice [ reserved "namespace" >> withPosition (T.Namespace <$> (star <|> identifier) <*> identifier)@@ -363,7 +363,7 @@ -- | Convenience wrapper for parsers expecting a position. -- -- The position will be retrieved BEFORE the parser itself is executed.-withPosition :: P.Stream s => Parser s (P.SourcePos -> a) -> Parser s a+withPosition :: P.TraversableStream s => Parser s (P.SourcePos -> a) -> Parser s a withPosition p = P.getSourcePos >>= \pos -> p <*> pure pos @@ -372,7 +372,7 @@ -- > data Foo = Foo { bar :: Bar, doc :: Docstring, pos :: Delta } -- > -- > parseFoo = withDocstring $ Foo <$> parseBar-withDocstring :: P.Stream s => Parser s (T.Docstring -> P.SourcePos -> a) -> Parser s a+withDocstring :: P.TraversableStream s => Parser s (T.Docstring -> P.SourcePos -> a) -> Parser s a withDocstring p = lastDocstring >>= \s -> do pos <- P.getSourcePos p <*> pure s <*> pure pos@@ -380,7 +380,7 @@ -- | A constant, type, or service definition. definition- :: (P.Stream s, P.Token s ~ Char) => Parser s (T.Definition P.SourcePos)+ :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.Definition P.SourcePos) definition = whiteSpace >> P.choice [ T.ConstDefinition <$> constant , T.TypeDefinition <$> typeDefinition@@ -390,7 +390,7 @@ -- | A type definition. typeDefinition- :: (P.Stream s, P.Token s ~ Char) => Parser s (T.Type P.SourcePos)+ :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.Type P.SourcePos) typeDefinition = P.choice [ T.TypedefType <$> typedef , T.EnumType <$> enum@@ -402,7 +402,7 @@ -- | A typedef is just an alias for another type. -- -- > typedef common.Foo Bar-typedef :: (P.Stream s, P.Token s ~ Char) => Parser s (T.Typedef P.SourcePos)+typedef :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.Typedef P.SourcePos) typedef = reserved "typedef" >> withDocstring (T.Typedef <$> typeReference <*> identifier <*> typeAnnotations) @@ -412,7 +412,7 @@ -- > enum Role { -- > User = 1, Admin -- >-enum :: (P.Stream s, P.Token s ~ Char) => Parser s (T.Enum P.SourcePos)+enum :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.Enum P.SourcePos) enum = reserved "enum" >> withDocstring ( T.Enum <$> identifier@@ -437,7 +437,7 @@ -- > 1: optional string message -- > 2: required string username -- > }-struct :: (P.Stream s, P.Token s ~ Char) => Parser s (T.Struct P.SourcePos)+struct :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.Struct P.SourcePos) struct = kind >>= \k -> withDocstring ( T.Struct k <$> identifier@@ -453,19 +453,19 @@ -- | A @union@ of types.-union :: (P.Stream s, P.Token s ~ Char) => Parser s (T.Struct P.SourcePos)+union :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.Struct P.SourcePos) union = struct {-# DEPRECATED union "Use struct." #-} -- | An @exception@ that can be raised by service methods.-exception :: (P.Stream s, P.Token s ~ Char) => Parser s (T.Struct P.SourcePos)+exception :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.Struct P.SourcePos) exception = struct {-# DEPRECATED exception"Use struct." #-} -- | Whether a field is @required@ or @optional@. fieldRequiredness- :: (P.Stream s, P.Token s ~ Char) => Parser s T.FieldRequiredness+ :: (P.TraversableStream s, P.Token s ~ Char) => Parser s T.FieldRequiredness fieldRequiredness = P.choice [ reserved "required" $> T.Required , reserved "optional" $> T.Optional@@ -473,7 +473,7 @@ -- | A struct field.-field :: (P.Stream s, P.Token s ~ Char) => Parser s (T.Field P.SourcePos)+field :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.Field P.SourcePos) field = withDocstring $ T.Field <$> optional (integer <* colon)@@ -486,7 +486,7 @@ -- | A value defined inside an @enum@.-enumDef :: (P.Stream s, P.Token s ~ Char) => Parser s (T.EnumDef P.SourcePos)+enumDef :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.EnumDef P.SourcePos) enumDef = withDocstring $ T.EnumDef <$> identifier@@ -497,7 +497,7 @@ -- | An string-only enum. These are a deprecated feature of Thrift and shouldn't -- be used.-senum :: (P.Stream s, P.Token s ~ Char) => Parser s (T.Senum P.SourcePos)+senum :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.Senum P.SourcePos) senum = reserved "senum" >> withDocstring ( T.Senum <$> identifier@@ -509,7 +509,7 @@ -- | A 'const' definition. -- -- > const i32 code = 1;-constant :: (P.Stream s, P.Token s ~ Char) => Parser s (T.Const P.SourcePos)+constant :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.Const P.SourcePos) constant = do reserved "const" withDocstring $@@ -522,7 +522,7 @@ -- | A constant value literal. constantValue- :: (P.Stream s, P.Token s ~ Char) => Parser s (T.ConstValue P.SourcePos)+ :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.ConstValue P.SourcePos) constantValue = withPosition $ P.choice [ P.try (string "0x") >> T.ConstInt <$> token PL.hexadecimal , either T.ConstFloat T.ConstInt@@ -537,7 +537,7 @@ constList- :: (P.Stream s, P.Token s ~ Char) => Parser s [T.ConstValue P.SourcePos]+ :: (P.TraversableStream s, P.Token s ~ Char) => Parser s [T.ConstValue P.SourcePos] constList = symbolic '[' *> loop [] where loop xs = P.choice@@ -549,7 +549,7 @@ constMap- :: (P.Stream s, P.Token s ~ Char)+ :: (P.TraversableStream s, P.Token s ~ Char) => Parser s [(T.ConstValue P.SourcePos, T.ConstValue P.SourcePos)] constMap = symbolic '{' *> loop [] where@@ -562,7 +562,7 @@ constantValuePair- :: (P.Stream s, P.Token s ~ Char)+ :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.ConstValue P.SourcePos, T.ConstValue P.SourcePos) constantValuePair = (,) <$> (constantValue <* colon)@@ -571,7 +571,7 @@ -- | A reference to a built-in or defined field. typeReference- :: (P.Stream s, P.Token s ~ Char)+ :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.TypeReference P.SourcePos) typeReference = P.choice [ baseType@@ -581,7 +581,7 @@ baseType- :: (P.Stream s, P.Token s ~ Char)+ :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.TypeReference P.SourcePos) baseType = withPosition $ P.choice [reserved s *> (v <$> typeAnnotations) | (s, v) <- bases]@@ -601,7 +601,7 @@ containerType- :: (P.Stream s, P.Token s ~ Char)+ :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.TypeReference P.SourcePos) containerType = withPosition $ P.choice [mapType, setType, listType] <*> typeAnnotations@@ -617,7 +617,7 @@ -- > service MyService { -- > // ... -- > }-service :: (P.Stream s, P.Token s ~ Char) => Parser s (T.Service P.SourcePos)+service :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.Service P.SourcePos) service = do reserved "service" withDocstring $@@ -633,7 +633,7 @@ -- > Foo getFoo() throws (1: FooDoesNotExist doesNotExist); -- > oneway void putBar(1: Bar bar); function- :: (P.Stream s, P.Token s ~ Char) => Parser s (T.Function P.SourcePos)+ :: (P.TraversableStream s, P.Token s ~ Char) => Parser s (T.Function P.SourcePos) function = withDocstring $ T.Function <$> ((reserved "oneway" $> True) <|> pure False)@@ -652,18 +652,18 @@ -- These do not usually affect code generation but allow for custom logic if -- writing your own code generator. typeAnnotations- :: (P.Stream s, P.Token s ~ Char) => Parser s [T.TypeAnnotation]+ :: (P.TraversableStream s, P.Token s ~ Char) => Parser s [T.TypeAnnotation] typeAnnotations = parens (many typeAnnotation) <|> pure [] -typeAnnotation :: (P.Stream s, P.Token s ~ Char) => Parser s T.TypeAnnotation+typeAnnotation :: (P.TraversableStream s, P.Token s ~ Char) => Parser s T.TypeAnnotation typeAnnotation = T.TypeAnnotation <$> identifier <*> (optional (equals *> literal) <* optionalSep) -optionalSep :: (P.Stream s, P.Token s ~ Char) => Parser s ()+optionalSep :: (P.TraversableStream s, P.Token s ~ Char) => Parser s () optionalSep = void $ optional (comma <|> semi) string :: forall s. (P.Stream s, P.Token s ~ Char) => String -> Parser s (P.Tokens s)