enh(reasonml) Simplify ReasonML syntax and align it with OCaml (#3795)

* reasonml: add more markup tests

* reasonml: sync with ocaml, update keywords

* reasonml: update changes.md

* reasonml: use literal regexps

* reasonml: use array of strs for keywords

* reasonml: put built-in types aside

* reasonml: classname -> scope

* reasonml: begin -> match

* reasonml: use variants for numbers

* reasonml: add operators back

* reasonml: fix operator handling of edge spacing
This commit is contained in:
Javier Chávarri 2023-08-18 04:42:57 +01:00 committed by GitHub
parent 198cb61883
commit 0ef63b9539
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 247 additions and 335 deletions

View File

@ -36,6 +36,7 @@ Core Grammars:
- fix(haskell) do not treat double dashes inside infix operators as comments [Zlondrej][]
- enh(rust) added `eprintln!` macro [qoheniac][]
- enh(leaf) update syntax to 4.0 [Samuel Bishop][]
- fix(reasonml) simplify syntax and align it with ocaml [jchavarri][]
- fix(swift) `warn_unqualified_access` is an attribute [Bradley Mackey][]
- enh(swift) macro attributes are highlighted as keywords [Bradley Mackey][]
@ -56,6 +57,7 @@ Dev tool:
[qoheniac]: https://github.com/qoheniac
[Samuel Bishop]: https://github.com/dannflor
[gondow]: https://github.com/gondow
[jchavarri]: https://github.com/jchavarri
[aana-h2]: https://github.com/aana-h2
[Nicholas Thompson]: https://github.com/NAThompson

View File

@ -6,301 +6,135 @@ Author: Gidi Meir Morris <oss@gidi.io>
Category: functional
*/
export default function(hljs) {
function orReValues(ops) {
return ops
.map(function(op) {
return op
.split('')
.map(function(char) {
return '\\' + char;
})
.join('');
})
.join('|');
}
const RE_IDENT = '~?[a-z$_][0-9a-zA-Z$_]*';
const RE_MODULE_IDENT = '`?[A-Z$_][0-9a-zA-Z$_]*';
const RE_PARAM_TYPEPARAM = '\'?[a-z$_][0-9a-z$_]*';
const RE_PARAM_TYPE = '\\s*:\\s*[a-z$_][0-9a-z$_]*(\\(\\s*(' + RE_PARAM_TYPEPARAM + '\\s*(,' + RE_PARAM_TYPEPARAM + '\\s*)*)?\\))?';
const RE_PARAM = RE_IDENT + '(' + RE_PARAM_TYPE + '){0,2}';
const RE_OPERATOR = "(" + orReValues([
'||',
'++',
'**',
'+.',
'*',
'/',
'*.',
'/.',
'...'
]) + "|\\|>|&&|==|===)";
const RE_OPERATOR_SPACED = "\\s+" + RE_OPERATOR + "\\s+";
const KEYWORDS = {
keyword:
'and as asr assert begin class constraint do done downto else end exception external '
+ 'for fun function functor if in include inherit initializer '
+ 'land lazy let lor lsl lsr lxor match method mod module mutable new nonrec '
+ 'object of open or private rec sig struct then to try type val virtual when while with',
built_in:
'array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 ref string unit ',
literal:
'true false'
};
const RE_NUMBER = '\\b(0[xX][a-fA-F0-9_]+[Lln]?|'
+ '0[oO][0-7_]+[Lln]?|'
+ '0[bB][01_]+[Lln]?|'
+ '[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)';
const NUMBER_MODE = {
className: 'number',
relevance: 0,
variants: [
{ begin: RE_NUMBER },
{ begin: '\\(-' + RE_NUMBER + '\\)' }
]
};
const OPERATOR_MODE = {
className: 'operator',
relevance: 0,
begin: RE_OPERATOR
};
const LIST_CONTENTS_MODES = [
{
className: 'identifier',
relevance: 0,
begin: RE_IDENT
},
OPERATOR_MODE,
NUMBER_MODE
const BUILT_IN_TYPES = [
"array",
"bool",
"bytes",
"char",
"exn|5",
"float",
"int",
"int32",
"int64",
"list",
"lazy_t|5",
"nativeint|5",
"ref",
"string",
"unit",
];
const MODULE_ACCESS_CONTENTS = [
hljs.QUOTE_STRING_MODE,
OPERATOR_MODE,
{
className: 'module',
begin: "\\b" + RE_MODULE_IDENT,
returnBegin: true,
relevance: 0,
end: "\.",
contains: [
{
className: 'identifier',
begin: RE_MODULE_IDENT,
relevance: 0
}
]
}
];
const PARAMS_CONTENTS = [
{
className: 'module',
begin: "\\b" + RE_MODULE_IDENT,
returnBegin: true,
end: "\.",
relevance: 0,
contains: [
{
className: 'identifier',
begin: RE_MODULE_IDENT,
relevance: 0
}
]
}
];
const PARAMS_MODE = {
begin: RE_IDENT,
end: '(,|\\n|\\))',
relevance: 0,
contains: [
OPERATOR_MODE,
{
className: 'typing',
begin: ':',
end: '(,|\\n)',
returnBegin: true,
relevance: 0,
contains: PARAMS_CONTENTS
}
]
};
const FUNCTION_BLOCK_MODE = {
className: 'function',
relevance: 0,
keywords: KEYWORDS,
variants: [
{
begin: '\\s(\\(\\.?.*?\\)|' + RE_IDENT + ')\\s*=>',
end: '\\s*=>',
returnBegin: true,
relevance: 0,
contains: [
{
className: 'params',
variants: [
{ begin: RE_IDENT },
{ begin: RE_PARAM },
{ begin: /\(\s*\)/ }
]
}
]
},
{
begin: '\\s\\(\\.?[^;\\|]*\\)\\s*=>',
end: '\\s=>',
returnBegin: true,
relevance: 0,
contains: [
{
className: 'params',
relevance: 0,
variants: [ PARAMS_MODE ]
}
]
},
{ begin: '\\(\\.\\s' + RE_IDENT + '\\)\\s*=>' }
]
};
MODULE_ACCESS_CONTENTS.push(FUNCTION_BLOCK_MODE);
const CONSTRUCTOR_MODE = {
className: 'constructor',
begin: RE_MODULE_IDENT + '\\(',
end: '\\)',
illegal: '\\n',
keywords: KEYWORDS,
contains: [
hljs.QUOTE_STRING_MODE,
OPERATOR_MODE,
{
className: 'params',
begin: '\\b' + RE_IDENT
}
]
};
const PATTERN_MATCH_BLOCK_MODE = {
className: 'pattern-match',
begin: '\\|',
returnBegin: true,
keywords: KEYWORDS,
end: '=>',
relevance: 0,
contains: [
CONSTRUCTOR_MODE,
OPERATOR_MODE,
{
relevance: 0,
className: 'constructor',
begin: RE_MODULE_IDENT
}
]
};
const MODULE_ACCESS_MODE = {
className: 'module-access',
keywords: KEYWORDS,
returnBegin: true,
variants: [
{ begin: "\\b(" + RE_MODULE_IDENT + "\\.)+" + RE_IDENT },
{
begin: "\\b(" + RE_MODULE_IDENT + "\\.)+\\(",
end: "\\)",
returnBegin: true,
contains: [
FUNCTION_BLOCK_MODE,
{
begin: '\\(',
end: '\\)',
relevance: 0,
skip: true
}
].concat(MODULE_ACCESS_CONTENTS)
},
{
begin: "\\b(" + RE_MODULE_IDENT + "\\.)+\\{",
end: /\}/
}
],
contains: MODULE_ACCESS_CONTENTS
};
PARAMS_CONTENTS.push(MODULE_ACCESS_MODE);
return {
name: 'ReasonML',
aliases: [ 're' ],
keywords: KEYWORDS,
illegal: '(:-|:=|\\$\\{|\\+=)',
keywords: {
$pattern: /[a-z_]\w*!?/,
keyword: [
"and",
"as",
"asr",
"assert",
"begin",
"class",
"constraint",
"do",
"done",
"downto",
"else",
"end",
"esfun",
"exception",
"external",
"for",
"fun",
"function",
"functor",
"if",
"in",
"include",
"inherit",
"initializer",
"land",
"lazy",
"let",
"lor",
"lsl",
"lsr",
"lxor",
"mod",
"module",
"mutable",
"new",
"nonrec",
"object",
"of",
"open",
"or",
"pri",
"pub",
"rec",
"sig",
"struct",
"switch",
"then",
"to",
"try",
"type",
"val",
"virtual",
"when",
"while",
"with",
],
built_in: BUILT_IN_TYPES,
literal: ["true", "false"],
},
illegal: /(:-|:=|\$\{|\+=)/,
contains: [
hljs.COMMENT('/\\*', '\\*/', { illegal: '^(#,\\/\\/)' }),
{
className: 'character',
begin: '\'(\\\\[^\']+|[^\'])\'',
illegal: '\\n',
scope: 'literal',
match: /\[(\|\|)?\]|\(\)/,
relevance: 0
},
hljs.QUOTE_STRING_MODE,
{
className: 'literal',
begin: '\\(\\)',
relevance: 0
},
{
className: 'literal',
begin: '\\[\\|',
end: '\\|\\]',
relevance: 0,
contains: LIST_CONTENTS_MODES
},
{
className: 'literal',
begin: '\\[',
end: '\\]',
relevance: 0,
contains: LIST_CONTENTS_MODES
},
CONSTRUCTOR_MODE,
{
className: 'operator',
begin: RE_OPERATOR_SPACED,
illegal: '-->',
relevance: 0
},
NUMBER_MODE,
hljs.C_LINE_COMMENT_MODE,
PATTERN_MATCH_BLOCK_MODE,
FUNCTION_BLOCK_MODE,
{
className: 'module-def',
begin: "\\bmodule\\s+" + RE_IDENT + "\\s+" + RE_MODULE_IDENT + "\\s+=\\s+\\{",
end: /\}/,
returnBegin: true,
keywords: KEYWORDS,
relevance: 0,
contains: [
{
className: 'module',
relevance: 0,
begin: RE_MODULE_IDENT
},
{
begin: /\{/,
end: /\}/,
relevance: 0,
skip: true
}
].concat(MODULE_ACCESS_CONTENTS)
hljs.COMMENT(/\/\*/, /\*\//, { illegal: /^(#,\/\/)/ }),
{ /* type variable */
scope: 'symbol',
match: /\'[A-Za-z_](?!\')[\w\']*/
/* the grammar is ambiguous on how 'a'b should be interpreted but not the compiler */
},
{ /* polymorphic variant */
scope: 'type',
match: /`[A-Z][\w\']*/
},
{ /* module or constructor */
scope: 'type',
match: /\b[A-Z][\w\']*/,
relevance: 0
},
{ /* don't color identifiers, but safely catch all identifiers with ' */
match: /[a-z_]\w*\'[\w\']*/,
relevance: 0
},
{
scope: 'operator',
match: /\s+(\|\||\+[\+\.]?|\*[\*\/\.]?|\/[\.]?|\.\.\.|\|>|&&|===?)\s+/,
relevance: 0
},
hljs.inherit(hljs.APOS_STRING_MODE, {
scope: 'string',
relevance: 0
}),
hljs.inherit(hljs.QUOTE_STRING_MODE, { illegal: null }),
{
scope: 'number',
variants: [
{ match: /\b0[xX][a-fA-F0-9_]+[Lln]?/ },
{ match: /\b0[oO][0-7_]+[Lln]?/ },
{ match: /\b0[bB][01_]+[Lln]?/ },
{ match: /\b[0-9][0-9_]*([Lln]|(\.[0-9_]*)?([eE][-+]?[0-9_]+)?)/ },
],
relevance: 0
},
MODULE_ACCESS_MODE
]
};
}

View File

@ -0,0 +1,10 @@
<span class="hljs-keyword">let</span> t = <span class="hljs-number">2</span>; <span class="hljs-comment">// Line comment</span>
<span class="hljs-comment">/* Regular comment */</span>
<span class="hljs-keyword">let</span> t = <span class="hljs-number">2</span>;
<span class="hljs-keyword">type</span> t =
| <span class="hljs-type">A</span>(<span class="hljs-built_in">string</span>)
| <span class="hljs-type">B</span>(<span class="hljs-built_in">int</span>);
<span class="hljs-comment">/* A(&quot;foo&quot;) -&gt; { TAG: 0, _0: &quot;Foo&quot; } */</span>
<span class="hljs-comment">/* B(2) -&gt; { TAG: 1, _0: 2 } */</span>

View File

@ -0,0 +1,10 @@
let t = 2; // Line comment
/* Regular comment */
let t = 2;
type t =
| A(string)
| B(int);
/* A("foo") -> { TAG: 0, _0: "Foo" } */
/* B(2) -> { TAG: 1, _0: 2 } */

View File

@ -1,22 +1,28 @@
<span class="hljs-comment">/* This is a simple function */</span>
<span class="hljs-keyword">let</span> greet =<span class="hljs-function"> (<span class="hljs-params">name</span>) =&gt;</span> <span class="hljs-string">&quot;Hello World&quot;</span>;
<span class="hljs-keyword">let</span> greet = (name) =&gt; <span class="hljs-string">&quot;Hello World&quot;</span>;
<span class="hljs-keyword">let</span> body = <span class="hljs-constructor">`Plain(<span class="hljs-string">&quot;uploaded &quot;</span> <span class="hljs-operator">++</span> <span class="hljs-params">cacheServiceConfig</span>.<span class="hljs-params">desc</span> <span class="hljs-operator">++</span> <span class="hljs-string">&quot;configuration data into cache on S3&quot;</span>)</span>;
<span class="hljs-keyword">let</span> body = <span class="hljs-type">`Plain</span>(<span class="hljs-string">&quot;uploaded &quot;</span><span class="hljs-operator"> ++ </span>cacheServiceConfig.desc<span class="hljs-operator"> ++ </span><span class="hljs-string">&quot;configuration data into cache on S3&quot;</span>);
<span class="hljs-keyword">let</span> getCacheConfigByEnv =
<span class="hljs-function"> (
<span class="hljs-params">environment<span class="hljs-typing">: environment,</span>
</span> <span class="hljs-params">cacheServiceConfig<span class="hljs-typing">: <span class="hljs-module"><span class="hljs-identifier">Js</span>.</span><span class="hljs-module"><span class="hljs-identifier">Dict</span>.</span>t(cachingServiceConfig)
</span> )</span> =&gt;</span>
switch (cacheServiceConfig) {
<span class="hljs-pattern-match">| <span class="hljs-constructor">Some(<span class="hljs-params">config</span>)</span> =&gt;</span> config
<span class="hljs-pattern-match">| <span class="hljs-constructor">None</span> =&gt;</span>
raise(<span class="hljs-constructor">InvalidEnvironment(<span class="hljs-string">&quot;Caching Service Coinfiguration is missing&quot;</span>)</span>)
(
environment: environment,
cacheServiceConfig: <span class="hljs-type">Js</span>.<span class="hljs-type">Dict</span>.t(cachingServiceConfig)
) =&gt;
<span class="hljs-keyword">switch</span> (cacheServiceConfig) {
| <span class="hljs-type">Some</span>(config) =&gt; config
| <span class="hljs-type">None</span> =&gt;
raise(<span class="hljs-type">InvalidEnvironment</span>(<span class="hljs-string">&quot;Caching Service Coinfiguration is missing&quot;</span>))
};
<span class="hljs-keyword">let</span> readCacheServiceConfigAndDecode =<span class="hljs-function"> (<span class="hljs-params">configJson</span>) =&gt;</span>
switch (configJson<span class="hljs-operator"> |&gt; </span><span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Js</span>.</span><span class="hljs-module"><span class="hljs-identifier">Json</span>.</span></span>decodeObject) {
<span class="hljs-pattern-match">| <span class="hljs-constructor">None</span> =&gt;</span> raise(Json.Decode.<span class="hljs-constructor">DecodeError(<span class="hljs-string">&quot;Invalid Cache Config&quot;</span>)</span>)
<span class="hljs-pattern-match">| <span class="hljs-constructor">Some(<span class="hljs-params">data</span>)</span> =&gt;</span>
data<span class="hljs-operator"> |&gt; </span><span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Js</span>.</span><span class="hljs-module"><span class="hljs-identifier">Dict</span>.</span></span>map(<span class="hljs-function">(. json) =&gt;</span> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">CachingServiceConfig</span>.</span></span>decode(json))
};
<span class="hljs-keyword">let</span> readCacheServiceConfigAndDecode = (configJson) =&gt;
<span class="hljs-keyword">switch</span> (configJson<span class="hljs-operator"> |&gt; </span><span class="hljs-type">Js</span>.<span class="hljs-type">Json</span>.decodeObject) {
| <span class="hljs-type">None</span> =&gt; raise(<span class="hljs-type">Json</span>.<span class="hljs-type">Decode</span>.<span class="hljs-type">DecodeError</span>(<span class="hljs-string">&quot;Invalid Cache Config&quot;</span>))
| <span class="hljs-type">Some</span>(data) =&gt;
data<span class="hljs-operator"> |&gt; </span><span class="hljs-type">Js</span>.<span class="hljs-type">Dict</span>.map((. json) =&gt; <span class="hljs-type">CachingServiceConfig</span>.decode(json))
};
<span class="hljs-keyword">let</span> ofSyntax = s =&gt;
<span class="hljs-keyword">switch</span> (s) {
| <span class="hljs-type">OCaml</span> =&gt; <span class="hljs-string">&quot;OCaml&quot;</span>
| <span class="hljs-type">Reason</span> =&gt; <span class="hljs-string">&quot;Reason&quot;</span>
};

View File

@ -19,4 +19,10 @@ let readCacheServiceConfigAndDecode = (configJson) =>
| None => raise(Json.Decode.DecodeError("Invalid Cache Config"))
| Some(data) =>
data |> Js.Dict.map((. json) => CachingServiceConfig.decode(json))
};
};
let ofSyntax = s =>
switch (s) {
| OCaml => "OCaml"
| Reason => "Reason"
};

View File

@ -1,5 +1,5 @@
<span class="hljs-keyword">let</span> i = <span class="hljs-number">14</span>;
<span class="hljs-keyword">let</span> i = <span class="hljs-number">(-14)</span>;
<span class="hljs-keyword">let</span> i = (-<span class="hljs-number">14</span>);
<span class="hljs-keyword">let</span> i = <span class="hljs-number">1000</span>;
<span class="hljs-keyword">let</span> i = <span class="hljs-number">0b100</span>;
<span class="hljs-keyword">let</span> i = <span class="hljs-number">0x1FF</span>;
@ -29,13 +29,13 @@
<span class="hljs-keyword">let</span> b = <span class="hljs-literal">true</span><span class="hljs-operator"> || </span><span class="hljs-literal">false</span>;
<span class="hljs-keyword">let</span> l = <span class="hljs-literal">[]</span>;
<span class="hljs-keyword">let</span> a = <span class="hljs-literal">[||]</span>;
<span class="hljs-keyword">let</span> arr = <span class="hljs-literal">[|<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>|]</span>;
<span class="hljs-keyword">let</span> b = <span class="hljs-literal">[<span class="hljs-identifier">item1</span>, <span class="hljs-identifier">item2</span>, <span class="hljs-operator">...</span><span class="hljs-identifier">theRest</span>]</span>;
<span class="hljs-keyword">let</span> arr = [|<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>|];
<span class="hljs-keyword">let</span> b = [item1, item2, ...theRest];
<span class="hljs-keyword">let</span> <span class="hljs-literal">()</span> = ignore(b);
<span class="hljs-keyword">let</span> str = <span class="hljs-string">&quot;a&quot;</span><span class="hljs-operator"> ++ </span><span class="hljs-string">&quot;b&quot;</span>;
<span class="hljs-keyword">let</span> c = <span class="hljs-character">&#x27;a&#x27;</span>;
<span class="hljs-keyword">let</span> c = <span class="hljs-character">&#x27;\xFF&#x27;</span>;
<span class="hljs-keyword">let</span> c = <span class="hljs-character">&#x27;\128&#x27;</span>;
<span class="hljs-keyword">let</span> c = <span class="hljs-character">&#x27;\n&#x27;</span>;
<span class="hljs-keyword">let</span> c = <span class="hljs-string">&#x27;a&#x27;</span>;
<span class="hljs-keyword">let</span> c = <span class="hljs-string">&#x27;\xFF&#x27;</span>;
<span class="hljs-keyword">let</span> c = <span class="hljs-string">&#x27;\128&#x27;</span>;
<span class="hljs-keyword">let</span> c = <span class="hljs-string">&#x27;\n&#x27;</span>;

View File

@ -1,19 +1,19 @@
<span class="hljs-keyword">let</span> decode =<span class="hljs-function"> <span class="hljs-params">json</span> =&gt;</span>
<span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Json</span>.</span><span class="hljs-module"><span class="hljs-identifier">Decode</span>.</span>{
query: json <span class="hljs-operator">|&gt;</span> field(<span class="hljs-string">&quot;query&quot;</span>, <span class="hljs-built_in">string</span>),
cacheKey: json <span class="hljs-operator">|&gt;</span> field(<span class="hljs-string">&quot;cacheKey&quot;</span>, <span class="hljs-built_in">string</span>),
desc: json <span class="hljs-operator">|&gt;</span> field(<span class="hljs-string">&quot;desc&quot;</span>, <span class="hljs-built_in">string</span>),
lambda: json <span class="hljs-operator">|&gt;</span> field(<span class="hljs-string">&quot;lambda&quot;</span>, <span class="hljs-built_in">string</span>),
}</span>;
<span class="hljs-keyword">let</span> decode = json =&gt;
<span class="hljs-type">Json</span>.<span class="hljs-type">Decode</span>.{
query: json<span class="hljs-operator"> |&gt; </span>field(<span class="hljs-string">&quot;query&quot;</span>, <span class="hljs-built_in">string</span>),
cacheKey: json<span class="hljs-operator"> |&gt; </span>field(<span class="hljs-string">&quot;cacheKey&quot;</span>, <span class="hljs-built_in">string</span>),
desc: json<span class="hljs-operator"> |&gt; </span>field(<span class="hljs-string">&quot;desc&quot;</span>, <span class="hljs-built_in">string</span>),
lambda: json<span class="hljs-operator"> |&gt; </span>field(<span class="hljs-string">&quot;lambda&quot;</span>, <span class="hljs-built_in">string</span>),
};
<span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Some</span>.</span><span class="hljs-module"><span class="hljs-identifier">Bucket</span>.</span><span class="hljs-module"><span class="hljs-identifier">Of</span>.</span>(
<span class="hljs-keyword">let</span> value = stuff();
)</span>;
<span class="hljs-type">Some</span>.<span class="hljs-type">Bucket</span>.<span class="hljs-type">Of</span>.(
<span class="hljs-keyword">let</span> value = stuff<span class="hljs-literal">()</span>;
);
<span class="hljs-keyword">let</span> value = <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Some</span>.</span><span class="hljs-module"><span class="hljs-identifier">Bucket</span>.</span><span class="hljs-module"><span class="hljs-identifier">Of</span>.</span></span>stuff<span class="hljs-literal">()</span>;
<span class="hljs-keyword">let</span> value = <span class="hljs-type">Some</span>.<span class="hljs-type">Bucket</span>.<span class="hljs-type">Of</span>.stuff<span class="hljs-literal">()</span>;
<span class="hljs-module-def"><span class="hljs-keyword">module</span> <span class="hljs-keyword">type</span> <span class="hljs-module">RewiredModule</span> = {
<span class="hljs-keyword">module</span> <span class="hljs-keyword">type</span> <span class="hljs-type">RewiredModule</span> = {
<span class="hljs-keyword">type</span> t = {
name: <span class="hljs-built_in">string</span>
};
}</span>;
};

View File

@ -1,20 +1,20 @@
<span class="hljs-keyword">let</span> message =
switch (person1) {
<span class="hljs-pattern-match">| <span class="hljs-constructor">School</span>.<span class="hljs-constructor">Teacher</span> =&gt;</span> <span class="hljs-string">&quot;Hello teacher!&quot;</span>
<span class="hljs-pattern-match">| <span class="hljs-constructor">School</span>.<span class="hljs-constructor">Director</span> =&gt;</span> <span class="hljs-string">&quot;Hello director!&quot;</span>
<span class="hljs-keyword">switch</span> (person1) {
| <span class="hljs-type">School</span>.<span class="hljs-type">Teacher</span> =&gt; <span class="hljs-string">&quot;Hello teacher!&quot;</span>
| <span class="hljs-type">School</span>.<span class="hljs-type">Director</span> =&gt; <span class="hljs-string">&quot;Hello director!&quot;</span>
};
<span class="hljs-keyword">let</span> message =
<span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">School</span>.</span>(
switch (person1) {
| <span class="hljs-module"><span class="hljs-identifier">Teacher</span> </span>=&gt; <span class="hljs-string">&quot;Hello teacher!&quot;</span>
| <span class="hljs-module"><span class="hljs-identifier">Director</span> </span>=&gt; <span class="hljs-string">&quot;Hello director!&quot;</span>
<span class="hljs-type">School</span>.(
<span class="hljs-keyword">switch</span> (person1) {
| <span class="hljs-type">Teacher</span> =&gt; <span class="hljs-string">&quot;Hello teacher!&quot;</span>
| <span class="hljs-type">Director</span> =&gt; <span class="hljs-string">&quot;Hello director!&quot;</span>
}
)</span>;
);
<span class="hljs-keyword">let</span> readCacheServiceConfigAndDecode =<span class="hljs-function"> (<span class="hljs-params">configJson</span>) =&gt;</span>
switch (configJson<span class="hljs-operator"> |&gt; </span><span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Js</span>.</span><span class="hljs-module"><span class="hljs-identifier">Json</span>.</span></span>decodeObject) {
<span class="hljs-pattern-match">| <span class="hljs-constructor">None</span> =&gt;</span> raise(Json.Decode.<span class="hljs-constructor">DecodeError(<span class="hljs-string">&quot;Invalid Cache Config&quot;</span>)</span>)
<span class="hljs-pattern-match">| <span class="hljs-constructor">Some(<span class="hljs-params">data</span>)</span> =&gt;</span>
data<span class="hljs-operator"> |&gt; </span><span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Js</span>.</span><span class="hljs-module"><span class="hljs-identifier">Dict</span>.</span></span>map(<span class="hljs-function">(. json) =&gt;</span> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">CachingServiceConfig</span>.</span></span>decode(json))
<span class="hljs-keyword">let</span> readCacheServiceConfigAndDecode = (configJson) =&gt;
<span class="hljs-keyword">switch</span> (configJson<span class="hljs-operator"> |&gt; </span><span class="hljs-type">Js</span>.<span class="hljs-type">Json</span>.decodeObject) {
| <span class="hljs-type">None</span> =&gt; raise(<span class="hljs-type">Json</span>.<span class="hljs-type">Decode</span>.<span class="hljs-type">DecodeError</span>(<span class="hljs-string">&quot;Invalid Cache Config&quot;</span>))
| <span class="hljs-type">Some</span>(data) =&gt;
data<span class="hljs-operator"> |&gt; </span><span class="hljs-type">Js</span>.<span class="hljs-type">Dict</span>.map((. json) =&gt; <span class="hljs-type">CachingServiceConfig</span>.decode(json))
};

View File

@ -0,0 +1,22 @@
<span class="hljs-comment">/* type variables */</span>
<span class="hljs-keyword">type</span> t(<span class="hljs-symbol">&#x27;a</span>) = <span class="hljs-built_in">list</span>(<span class="hljs-symbol">&#x27;a</span>);
<span class="hljs-keyword">let</span> f = (a: <span class="hljs-built_in">list</span>(<span class="hljs-symbol">&#x27;a</span>)): <span class="hljs-symbol">&#x27;a</span> =&gt; <span class="hljs-type">List</span>.hd(a);
<span class="hljs-comment">/* polymorphic variants */</span>
<span class="hljs-keyword">type</span> t = [ | <span class="hljs-type">`A</span> | <span class="hljs-type">`B</span>];
<span class="hljs-comment">/* variants */</span>
<span class="hljs-keyword">type</span> result =
| <span class="hljs-type">Sat</span>
| <span class="hljs-type">Unsat</span>
| <span class="hljs-type">Unknown</span>;
<span class="hljs-comment">/* module and module types */</span>
<span class="hljs-keyword">module</span> <span class="hljs-keyword">type</span> <span class="hljs-type">S</span> = {<span class="hljs-keyword">let</span> compute: <span class="hljs-built_in">unit</span> =&gt; <span class="hljs-built_in">unit</span>;};
<span class="hljs-keyword">module</span> <span class="hljs-type">Impl</span>: <span class="hljs-type">S</span> = {
<span class="hljs-keyword">let</span> compute = <span class="hljs-literal">()</span> =&gt; <span class="hljs-literal">()</span>;
};
<span class="hljs-comment">/* types with attributes */</span>
[@bs.deriving jsConverter]
<span class="hljs-keyword">type</span> action = [ | <span class="hljs-type">`Click</span> | [@bs.<span class="hljs-keyword">as</span> <span class="hljs-string">&quot;submit&quot;</span>] <span class="hljs-type">`Submit</span> | <span class="hljs-type">`Cancel</span>];

View File

@ -0,0 +1,22 @@
/* type variables */
type t('a) = list('a);
let f = (a: list('a)): 'a => List.hd(a);
/* polymorphic variants */
type t = [ | `A | `B];
/* variants */
type result =
| Sat
| Unsat
| Unknown;
/* module and module types */
module type S = {let compute: unit => unit;};
module Impl: S = {
let compute = () => ();
};
/* types with attributes */
[@bs.deriving jsConverter]
type action = [ | `Click | [@bs.as "submit"] `Submit | `Cancel];