From db43cad603bdbb21b49eedb98560a2a37c46f2c5 Mon Sep 17 00:00:00 2001 From: Daniel Brice Date: Sat, 29 Sep 2018 23:25:34 -0700 Subject: [PATCH] add comprehensive (and passing!) test suite --- Haskell.sublime-syntax | 31 ++- README.md | 20 ++ syntax_test_haskell.hs | 593 ++++++++++++++++++++++++++++++++--------- 3 files changed, 509 insertions(+), 135 deletions(-) diff --git a/Haskell.sublime-syntax b/Haskell.sublime-syntax index dd8060d..2259b5c 100644 --- a/Haskell.sublime-syntax +++ b/Haskell.sublime-syntax @@ -17,7 +17,7 @@ variables: id_tail: '[a-zA-Z0-9_'']*' type_id: '[A-Z]{{id_tail}}' val_id: '[a-z_]{{id_tail}}' - op_id: '[!#$%&*+./<=>?@\\\^|\-~:]+' + op_id: '[!#$%&*+./<=>?@\\\^|\-~:∷→⇒]+' contexts: main: @@ -55,7 +55,7 @@ contexts: scope: entity.other.inherited-class.haskell - match: '\b{{val_id}}\b' scope: variable.other.generic-type.haskell - - match: '(=>|⇒)' + - match: '{{op_id}}' scope: keyword.operator.haskell - match: '\b(import)\b' captures: @@ -67,7 +67,7 @@ contexts: - match: '(qualified|as|hiding)' scope: keyword.other.haskell - include: module_name - - include: module_exports + - include: module_imports - include: comments - match: '(deriving)\s*\(' captures: @@ -224,19 +224,26 @@ contexts: - match: '$' pop: true - include: block_comment + imports_exports: + - include: comments + - match: '\b({{type_id}})(\(.[^\)]*\)|)' + captures: + 1: storage.type.haskell + - match: '\(({{op_id}})\)' + captures: + 1: keyword.operator.haskell + - match: '\)' + pop: true module_exports: - match: '\(' push: - meta_scope: meta.declaration.exports.haskell - - include: comments - - match: '\b({{type_id}})(\(.[^\)]*\)|)' - captures: - 1: storage.type.haskell - - match: '\(({{op_id}})\)' - captures: - 1: keyword.operator.haskell - - match: '\)' - pop: true + - include: imports_exports + module_imports: + - match: '\(' + push: + - meta_scope: meta.declaration.imports.haskell + - include: imports_exports module_name: - match: '{{type_id}}' scope: support.other.module.haskell diff --git a/README.md b/README.md index 7aa2991..9f335f8 100644 --- a/README.md +++ b/README.md @@ -45,3 +45,23 @@ Permission granted to anyone who posesses the software to use, distribute, and m THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. **Pull requests welcomed!** While I don't have time to work on feature requests, I will happily consider any pull requests and either merge them or give feedback. + +## Versioning Scheme + +Releases will be identified via Git tags, which will always be in the format + +``` +v{{ MAJOR }}.{{ MINOR }}.{{ PATCH }} +``` + +where `MAJOR`, `MINOR`, and `PATCH` are non-negative integers. + +Release version numbers are chosen by considering the following rules, in short-circuit order: + +* Whenever existing assertions in the test suit are changed or removed, we will bump the `MAJOR` version (with `MINOR` and `PATCH` rolling over to `0`). + +* Whenever new assertions are added that enhance the granularity of syntax highlighting, we will bump the `MINOR` version (with `PATCH` rolling over to `0`). + +* Whenever a bug is fixed, with or without adding assertions, we will bump the `PATCH` version. + +It's worth noting that the distinction between `MINOR` bumps and `PATCH` bumps is somewhat vague, sometimes making the decision a matter of taste. The rule defining a `MAJOR` bump, however, is unambiguous. diff --git a/syntax_test_haskell.hs b/syntax_test_haskell.hs index 2655603..086b443 100644 --- a/syntax_test_haskell.hs +++ b/syntax_test_haskell.hs @@ -1,249 +1,596 @@ -- SYNTAX TEST "Packages/User/Haskell.sublime-syntax" -{-# LANGUAGE FlexibleInstances, OverloadedStrings, UnicodeSyntax #-} --- ^^^^^^^^ keyword.other.preprocessor.haskell +{-# LANGUAGE FlexibleContexts, FlexibleInstances, OverloadedStrings, TypeOperators, UndecidableInstances, UnicodeSyntax #-} +-- ^^^^^^^^ keyword.other.preprocessor +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor +-- ^ -meta.preprocessor module Main ( +-- ^^^ keyword.other +-- ^^^^^^^^^ meta.declaration.module -meta.declaration.exports +-- ^^ meta.declaration.module meta.declaration.exports Foo(str, int), +-- ^^^ storage.type +-- ^^^^^^^^^^ -storage.type -- a nice comment in the module exports list +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line Fooable(..), +-- ^^^^^^^ storage.type +-- ^^^^ -storage.type DeriveMoreThanOne, main, (-->), - (+:), +-- ^^^^^^^^ -comment.line +-- ^ -keyword.operator +-- ^^^ keyword.operator +-- ^ -keyword.operator + (++:), +-- ^ -keyword.operator +-- ^^^ keyword.operator +-- ^ -keyword.operator addEmUp, -) where + ) where +-- ^^^^^ keyword.other +-- ^^ meta.declaration.exports +-- ^ -meta.declaration.exports +-- ^^^^^^^^ meta.declaration.module +-- ^ -meta.declaration.module import Prelude hiding (Traversable(traverse, sequenceA)) +-- ^^^ keyword.other +-- ^^^^^^ keyword.other +-- ^^^^^^^ support.other.module +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.declaration.imports +-- ^^^^^^^^^^^^^^^^^^^ -meta.declaration.import +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.import +-- ^ -meta.import -meta.declaration.imports import System.Exit (ExitCode(..), exitWith) -import Data.String +import qualified Data.String ----- --- Original Tests ----- - -x0 = 23*36 -- single line comment --- ^^ punctuation.definition.comment.haskell --- ^^^^^^^^^^^^^^^^^^^^^^^ comment.line.double-dash.haskell -x1 = 23*36 --- <- - comment.line.double-dash.haskell - -x2 = {- block comment -} 23*36 --- ^^ punctuation.definition.comment.begin.haskell --- ^^^^^^^^^^^^^^^^^^^ comment.block.haskell --- ^^ punctuation.definition.comment.end.haskell --- ^ - comment.block.haskell - -x3 = {- {-# #-} -} 23*36 --- ^^ punctuation.definition.comment.begin.haskell --- ^^^^^^^^^^^^^ comment.block.haskell - meta.preprocessor.haskell --- ^^ punctuation.definition.comment.end.haskell --- ^ - comment.block.haskell - -x4 = {- {- #-} -} 23*36 --- ^^ punctuation.definition.comment.begin.haskell --- ^^^^^^^^^^^^ comment.block.haskell --- ^^ punctuation.definition.comment.end.haskell --- ^ - comment.block.haskell - -x5 = {- {- -} -} 23*36 --- ^^ punctuation.definition.comment.begin.haskell --- ^^^^^^^^^^^ comment.block.haskell --- ^^ punctuation.definition.comment.end.haskell --- ^ - comment.block.haskell - -x6 = {- {-# -} -} 23*36 --- ^^ punctuation.definition.comment.begin.haskell --- ^^^^^^^^^^^^ comment.block.haskell - meta.preprocessor.haskell --- ^^ punctuation.definition.comment.end.haskell --- ^ - comment.block.haskell - -x7 = {- {-# {- test -} -} -} 23*36 --- ^^ punctuation.definition.comment.begin.haskell --- ^^^^^^^^^^^^^^^^^^^^^^^ comment.block.haskell - meta.preprocessor.haskell --- ^^ punctuation.definition.comment.end.haskell --- ^ - comment.block.haskell - -class (Functor t, Foldable t) => Traversable t where --- ^^ keyword.other.haskell --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.declaration.class.haskell - {-# MINIMAL traverse | sequenceA #-} --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor.haskell --- ^ - meta.preprocessor.haskell - - -- | Map each element of a structure to an action, - -- evaluate these actions from left to right, and - -- collect the results. For a version that ignores - -- the results see 'Data.Foldable.traverse_'. --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line.double-dash.haskell - traverse :: Applicative f => --- ^^^^^^^^ entity.name.function.haskell --- ^^ keyword.other.double-colon.haskell --- ^^^^^^^^^^^ storage.type.haskell --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.type-declaration.haskell --- ^^ keyword.other.big-arrow.haskell - (a -> f b) --- ^^^^^^^^^^^^ meta.function.type-declaration.haskell --- ^^ keyword.other.arrow.haskell - -> t a --- ^^^^^^^^ meta.function.type-declaration.haskell --- ^^ keyword.other.arrow.haskell - -> f (t b) --- ^^^^^^^^^^^^ meta.function.type-declaration.haskell --- ^^ keyword.other.arrow.haskell - traverse f = sequenceA . fmap f --- ^^^^^^^^^^^^^ meta.function.type-declaration.haskell --- ^ keyword.operator.haskell --- ^ keyword.operator.haskell +data DeriveMoreThanOne = MkDeriveMoreThanOne deriving (Eq, Read, Show) +-- ^ keyword.other +-- ^^^^^^^^^^^^^^^^^ storage.type +-- ^ keyword.operator +-- ^^^^^^^^ keyword.other +-- ^^ entity.other.inherited-class +-- ^^^^ entity.other.inherited-class +-- ^^^^ entity.other.inherited-class - -- | Evaluate each action in the structure from - -- left to right, and collect the results. - -- For a version that ignores the results see - -- 'Data.Foldable.sequenceA_'. - sequenceA ∷ Applicative f ⇒ t (f a) → f (t a) --- ^^^^^^^^^ entity.name.function.haskell --- ^ keyword.other.double-colon.haskell --- ^^^^^^^^^^^ storage.type.haskell --- ^ keyword.other.big-arrow.haskell --- ^ keyword.other.arrow.haskell - sequenceA = traverse id --- ^ keyword.operator.haskell ---- --- Specific Tests +-- top-level definitions are names ---- - --- deriving more than one type class -data DeriveMoreThanOne = MkDeriveMoreThanOne deriving (Eq, Read, Show) - --- arrows toUnit :: DeriveMoreThanOne -> () +-- ^^^ entity.name.function +-- ^^ keyword.operator +-- ^^^^^^^^^^^^^^^^^ storage.type +-- ^^ keyword.operator toUnit _ = () +-- ^^^ -entity.name.function +-- ^ keyword.operator --- question marks in operators -(!!?) :: DeriveMoreThanOne -> DeriveMoreThanOne -> DeriveMoreThanOne + +---- +-- operators with question marks +---- +(!!?) :: a -> b -> DeriveMoreThanOne +-- ^ entity.name.function +-- ^ -entity.name.function _ !!? _ = MkDeriveMoreThanOne +-- ^^ keyword.operator +-- ^ -keyword.operator --- operators that start with '--' + +---- +-- operators starting with `--` +---- (-->) :: (a -> b) -> (b -> c) -> a -> c +-- ^ entity.name.function +-- ^ -entity.name.function +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -comment f --> g = g . f +-- ^^ keyword.operator +-- ^ -keyword.operator +-- ^^^^^^^^^^^^^ -comment + +---- -- operators that end with '--' +---- (<--) :: (b -> c) -> (a -> b) -> a -> c +-- ^ entity.name.function +-- ^ -entity.name.function +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -comment f <-- g = f . g +-- ^^ keyword.operator +-- ^ -keyword.operator +-- ^^^^^^^^^^^^^ -comment + +---- -- comments in class and instance declarations +---- class SomeClass a -- some comment +-- ^^ keyword.other +-- ^^^^^^^^^ entity.other.inherited-class +-- ^^^^^^^^^^^^^^^ comment.line instance SomeClass a -- some comment +-- ^^^^^ keyword.other +-- ^^^^^^^^^ entity.other.inherited-class +-- ^^^^^^^^^^^^^^^ comment.line + +---- -- classes can have numbers and primes in their names +---- class Class0 a +-- ^^^^^^ entity.other.inherited-class +-- ^ -entity.other.inherited-class instance Class0 Int +-- ^^^^^^ entity.other.inherited-class +-- ^ -entity.other.inherited-class class Class' a +-- ^^^^^^ entity.other.inherited-class +-- ^ -entity.other.inherited-class instance Class' Int +-- ^^^^^^ entity.other.inherited-class +-- ^ -entity.other.inherited-class + +---- -- class constraints and contexts +---- class (Class0 a, Class' a) => Class0' a +-- ^^^^ -entity.other.inherited-class +-- ^^^^^^ entity.other.inherited-class +-- ^^^^ -entity.other.inherited-class +-- ^^^^^^ entity.other.inherited-class +-- ^^^^^^^ -entity.other.inherited-class +-- ^^^^^^^ entity.other.inherited-class +-- ^^^ -entity.other.inherited-class +-- ^^^^^^^^^^^^^^^^^^^^^^^^ -keyword.operator +-- ^^ keyword.operator +-- ^^^^^^^^^^^ -keyword.operator +-- ^^ keyword.other +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -keyword.other instance Class0 a => Class0 (Maybe a) -instance Class' a => Class' (Maybe a) -instance (Class0 a, Class' a) => Class0' (Maybe a) +-- ^^^^^ keyword.other +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -keyword.other +-- ^^^^^^ -entity.other.inherited-class +-- ^^^^^^ entity.other.inherited-class +-- ^^^^^^ -entity.other.inherited-class +-- ^^^^^^ entity.other.inherited-class +-- ^ -entity.other.inherited-class +-- ^^^^^^^^^^^^^^^ -keyword.operator +-- ^^ keyword.operator +-- ^^^^^^^^^^^^^^^^^^ -keyword.operator + +---- -- functions with primes in their names +---- someFunc' :: Char -> Int -> String +-- ^^^^^^ entity.name.function +-- ^ -entity.name.function someFunc' char int = replicate int char +-- ^^^^^^ -entity.name.function + +---- -- types with primes in their names +---- newtype Foo' = Foo' { unFoo' :: Foo } +-- ^^^^ keyword.other +-- ^ -keyword.other +-- ^^^^ storage.type +-- ^ -storage.type --- operators, guards, and contexts -(+:) :: Enum a => Int -> a -> a -n +: x + +---- +-- operators, guards +---- +(++:) :: Enum a => Int -> a -> a +-- ^ entity.name.function +-- ^ -entity.name.function +-- ^ -keyword.operator +-- ^^ keyword.operator +-- ^ -keyword.operator +n ++: x +-- ^^ keyword.operator +-- ^ -keyword.operator | n <= 0 = x - | otherwise = (n - 1) +: succ x +-- ^ -keyword.operator +-- ^ keyword.operator +-- ^ -keyword.operator +-- ^ -keyword.operator +-- ^ keyword.operator +-- ^ -keyword.operator + | otherwise = (n - 1) ++: succ x +-- ^ -keyword.operator +-- ^ keyword.operator +-- ^ -keyword.operatorx +-- ^ -keyword.operator +-- ^ keyword.operator +-- ^ -keyword.operator +-- ^ -keyword.operator +-- ^^^ keyword.operator +-- ^ -keyword.operator + --- infix functions, operator sections, list literals, char literals +---- +-- infix functions, operator sections, list literals, char literals, where blocks +---- someList :: [Char] -someList = (5 +:) `fmap1'` ['a', 'b', 'c'] +someList = (5 ++:) `fmap1'` ['a', 'b', 'c'] +-- ^^^ keyword.operator +-- ^^ -keyword +-- ^^^^^^^^ keyword.operator +-- ^^ -keyword +-- ^ punctuation.definition.string.begin +-- ^ string +-- ^ punctuation.definition.string.end where +-- ^^^^ keyword.other +-- ^ -keyword.other fmap1' :: (Char -> Char) -> [Char] -> [Char] +-- ^ -entity +-- ^^^^^^ entity.name.function +-- ^ -keyword -entity +-- ^^ keyword.operator +-- ^ -keyword fmap1' = fmap +-- ^^^^^^^^^^^^^^^ -entity +-- ^ keyword.operator + ---- --- Random Stuff +-- `do` block ---- - main :: IO () main = do +-- ^^ -entity -keyword +-- ^ keyword.operator +-- ^ -keyword +-- ^^ keyword.control print (tryLet "this") let x = 1 + 1 +-- ^ -keyword +-- ^^^ keyword.other +-- ^ -keyword let y = (+) 2 2 +-- ^ -keyword +-- ^^^ keyword.other +-- ^ -keyword z <- pure 3 +-- ^ -keyword +-- ^^ keyword.operator +-- ^ -keyword print (addEmUp x y z) putStrLn (str myFoo) exitWith ExitSuccess + +---- +-- `let` block, and strings +---- +tryLet :: String -> String +tryLet this = + let that = this ++ " that" +-- ^ -keyword +-- ^^^ keyword.other +-- ^ -keyword +-- ^ -keyword +-- ^^ keyword.operator +-- ^ -keyword -string +-- ^^^^^^^ string.quoted.double +-- ^ -string + those = that ++ " those" +-- ^ -keyword +-- ^^ keyword.operator +-- ^ -keyword -string +-- ^^^^^^^^ string.quoted.double +-- ^ -string + these = those ++ " these" +-- ^ -keyword +-- ^^ keyword.operator +-- ^ -keyword -string +-- ^^^^^^^^ string.quoted.double +-- ^ -string + in these +-- ^ -keyword +-- ^^ keyword.other +-- ^ -keyword + + +---- +-- function declaration with signature on next line +---- addEmUp +-- ^^^^ entity.name.function +-- ^ -entity :: Int -> Int -> Int -> Int +-- ^ -keyword +-- ^^ keyword.operator +-- ^ -keyword addEmUp x y z = x + y + z +-- ^^^^^^^^^^^^^^^^^^^^^^ -entity + +---- +-- record accessors are names +---- data Foo = Foo { str :: String +-- ^ -entity +-- ^^^ entity.name.function +-- ^ -entity -keyword +-- ^^ keyword.operator +-- ^ -keyword , int :: Int +-- ^ -entity +-- ^^^ entity.name.function +-- ^ -entity -keyword +-- ^^ keyword.operator +-- ^ -keyword } deriving Show -tryLet :: String -> String -tryLet this = - let that = this ++ " that" - those = that ++ " those" - these = those ++ " these" - in these - emptyFoo :: Foo emptyFoo = Foo "" 0 + +---- +-- class methods are names +---- class Fooable a where toFoo :: a -> Foo +-- ^ -entity +-- ^^^^^ entity.name.function +-- ^^^ -entity -keyword +-- ^^ keyword.operator +-- ^ -keyword fromFoo :: Foo -> a +-- ^ -entity +-- ^^^^^^^ entity.name.function +-- ^ -entity -keyword +-- ^^ keyword.operator +-- ^ -keyword (<=>) :: Foo -> a -> Bool +-- ^ -entity +-- ^^^ entity.name.function +-- ^^^^ -entity -function +-- ^^ keyword.operator +-- ^ -keyword + +---- +-- `&&` is an operator +---- instance Fooable Foo where toFoo = id fromFoo = id x <=> y = str x == str y && int x == int y +-- ^ -keyword +-- ^^ keyword.operator +-- ^ -keyword + +---- +-- record update syntax +--- instance Fooable String where toFoo x = emptyFoo { str = x } +-- ^^^^^^^^^^^^^^^^^^^^^^ -entity +-- ^ -keyword +-- ^ keyword.operator +-- ^ -keyword fromFoo = str x <=> y = str x == y instance Fooable Int where toFoo x = emptyFoo { int = x } +-- ^^^^^^^^^^^^^^^^^^^^^^ -entity +-- ^ -keyword +-- ^ keyword.operator +-- ^ -keyword fromFoo = int x <=> y = int x == y + +---- +-- classes and instances with no methods +---- class Show a => Foolike a +-- ^^^^^^^^^^^^^^^^^^^^^^ meta.declaration.class +-- ^ -meta.declaration.class instance Foolike Foo - +-- ^^^^^^^^^^^^^^^^^ meta.declaration.class +-- ^ -meta.declaration.class instance Foolike a => Foolike [a] +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.declaration.class +-- ^ -meta.declaration.class + + +---- +-- types operators +---- +type a :*: b = (a, Bool -> b) +-- ^ keyword.other +-- ^^^ -keyword +-- ^^^ keyword.operator +-- ^^^ -keyword +-- ^ keyword.operator +-- ^^^^^^^^^^ -keyword +-- ^^ keyword.operator +-- ^ -keyword + +instance (Show (x -> a), Foolike a) => Foolike (x -> a) +-- ^ -keyword +-- ^^ keyword.operator +-- ^^^^^^^^^^^^^^^^ -keyword +-- ^^ keyword.operator +-- ^^^^^^^^^^^^ -keyword +-- ^^ keyword.operator +-- ^ -keyword +instance (Show (Bool -> b), Foolike a, Foolike b) => Foolike (a :*: b) +-- ^ -keyword +-- ^^ keyword.operator +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -keyword +-- ^^ keyword.operator +-- ^^^^^^^^^^^^ -keyword +-- ^^^ keyword.operator +-- ^ -keyword + +---- +-- record syntax +---- myFoo :: Foo myFoo = Foo { str = multiLineString :: String +-- ^^^^^^^^^ -entity +-- ^ -keyword +-- ^ keyword.operator +-- ^ -keyword , int = 37 +-- ^^^^^^^^^^^^ -entity +-- ^ -keyword +-- ^ keyword.operator +-- ^ -keyword } -- where (this is to close the 'Foolike' declaration) -multiLineString :: IsString a => a + +---- +-- multiline strings +---- +multiLineString :: Data.String.IsString a => a multiLineString = "here\ \is\ \a\ \multiline\ \string" +-- ^^^^^^^^^ string.quoted.double +-- ^ constant.character.escape.multi-line +-- ^ -string -data OneLine a = OneLine { unOneLine :: a } +---- +-- records written on one line +---- +newtype OneLine a = OneLine { unOneLine :: a } +-- ^^^^ keyword.other +-- ^ -keyword -storage +-- ^^^^^^^ storage.type +-- ^^^ -keyword -storage +-- ^ keyword.operator +-- ^^^^^^^^^^^ -keyword -entity +-- ^^^^^^^^^ entity.name.function +-- ^ -keyword -entity +-- ^^ keyword.operator +-- ^ -keyword + + +---- +-- classes written on one line +---- class OneLiner a where oneLiner :: a -> OneLine a +-- ^^ keyword.other +-- ^ -keyword -entity +-- ^^^^^^^^ entity.other.inherited-class +-- ^^^ -entity -keyword +-- ^^^^^ keyword.other +-- ^ -keyword -entity +-- ^^^^^^^^ entity.name.function +-- ^ -entity -keyword +-- ^^ keyword.operator +-- ^ -keyword + + +---- +-- original tests +---- +x0 = 23*36 -- single line comment +-- ^^ punctuation.definition.comment +-- ^^^^^^^^^^^^^^^^^^^^^^ comment.line +x1 = 23*36 +-- <- - comment.line + +x2 = {- block comment -} 23*36 +-- ^^ punctuation.definition.comment.begin +-- ^^^^^^^^^^^^^^^^^^^ comment.block +-- ^^ punctuation.definition.comment.end +-- ^ -comment.block + +x3 = {- {-# #-} -} 23*36 +-- ^^ punctuation.definition.comment.begin +-- ^^^^^^^^^^^^^ comment.block -meta.preprocessor +-- ^^ punctuation.definition.comment.end +-- ^ -comment.block + +x4 = {- {- #-} -} 23*36 +-- ^^ punctuation.definition.comment.begin +-- ^^^^^^^^^^^^ comment.block +-- ^^ punctuation.definition.comment.end +-- ^ -comment.block + +x5 = {- {- -} -} 23*36 +-- ^^ punctuation.definition.comment.begin +-- ^^^^^^^^^^^ comment.block +-- ^^ punctuation.definition.comment.end +-- ^ -comment.block + +x6 = {- {-# -} -} 23*36 +-- ^^ punctuation.definition.comment.begin +-- ^^^^^^^^^^^^ comment.block -meta.preprocessor +-- ^^ punctuation.definition.comment.end +-- ^ -comment.block + +x7 = {- {-# {- test -} -} -} 23*36 +-- ^^ punctuation.definition.comment.begin +-- ^^^^^^^^^^^^^^^^^^^^^^^ comment.block -meta.preprocessor +-- ^^ punctuation.definition.comment.end +-- ^ -comment.block + +class (Functor t, Foldable t) => Traversable t where +-- ^^ keyword.other +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.declaration.class + {-# MINIMAL traverse | sequenceA #-} +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.preprocessor +-- ^ -meta.preprocessor + + -- | Map each element of a structure to an action, + -- evaluate these actions from left to right, and + -- collect the results. For a version that ignores + -- the results see 'Data.Foldable.traverse_'. +-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line.haskell + traverse :: Applicative f => +-- ^^^^^^^^ entity.name.function +-- ^^ keyword.operator +-- ^^^^^^^^^^^ storage.type +-- ^^ keyword.operator + (a -> f b) +-- ^^ keyword.operator + -> t a +-- ^^ keyword.operator + -> f (t b) +-- ^^ keyword.operator + traverse f = sequenceA . fmap f +-- ^ keyword.operator +-- ^ keyword.operator + + -- | Evaluate each action in the structure from + -- left to right, and collect the results. + -- For a version that ignores the results see + -- 'Data.Foldable.sequenceA_'. + sequenceA ∷ Applicative f ⇒ t (f a) → f (t a) +-- ^^^^^^^^^ entity.name.function.haskell +-- ^ keyword.operator +-- ^^^^^^^^^^^ storage.type +-- ^ keyword.operator +-- ^ keyword.operator + sequenceA = traverse id +-- ^ keyword.operator.haskell