1- import { none } from 'fp-ts/lib/Option'
1+ import { none , Option , some } from 'fp-ts/lib/Option'
22import { Reader , reader , ask } from 'fp-ts/lib/Reader'
33import { array , empty } from 'fp-ts/lib/Array'
44import * as ts from 'typescript'
@@ -44,29 +44,35 @@ const getMemberName = (m: M.Member, position: number): string => {
4444 return m . name . getOrElseL ( ( ) => `value${ position } ` )
4545}
4646
47- const getDomainParameterName = ( type : M . Type ) : string => {
47+ const getDomainParameterName = ( type : M . Type ) : Option < string > => {
4848 switch ( type . kind ) {
49- case 'TypeReference' :
50- return getFirstLetterLowerCase ( type . name )
51- case 'TupleType' :
52- return 'tuple'
53- case 'FunctionType' :
54- return 'f'
49+ case 'Ref' :
50+ return some ( getFirstLetterLowerCase ( type . name ) )
51+ case 'Tuple' :
52+ return some ( 'tuple' )
53+ case 'Fun' :
54+ return some ( 'f' )
55+ case 'Unit' :
56+ return none
5557 }
5658}
5759
5860const getTypeNode = ( type : M . Type ) : ts . TypeNode => {
5961 switch ( type . kind ) {
60- case 'TypeReference ' :
62+ case 'Ref ' :
6163 return ts . createTypeReferenceNode ( type . name , type . parameters . map ( p => getTypeNode ( p ) ) )
62- case 'TupleType ' :
63- return ts . createTupleTypeNode ( [ getTypeNode ( type . fst ) , getTypeNode ( type . snd ) , ... type . other . map ( getTypeNode ) ] )
64- case 'FunctionType ' :
64+ case 'Tuple ' :
65+ return ts . createTupleTypeNode ( type . types . map ( getTypeNode ) )
66+ case 'Fun ' :
6567 return ts . createFunctionTypeNode (
6668 undefined ,
67- [ getParameterDeclaration ( getDomainParameterName ( type . domain ) , getTypeNode ( type . domain ) ) ] ,
69+ getDomainParameterName ( type . domain )
70+ . map ( domainName => [ getParameterDeclaration ( domainName , getTypeNode ( type . domain ) ) ] )
71+ . getOrElse ( [ ] ) ,
6872 getTypeNode ( type . codomain )
6973 )
74+ case 'Unit' :
75+ return ts . createTypeReferenceNode ( 'undefined' , [ ] )
7076 }
7177}
7278
@@ -83,9 +89,9 @@ const getDataLiteralEncoding = (d: M.Data): AST<Array<ts.Node>> => {
8389 )
8490 return [
8591 getTypeAliasDeclaration (
86- d . introduction . name ,
92+ d . name ,
8793 unionType ,
88- d . introduction . parameters . map ( p =>
94+ d . parameterDeclarations . map ( p =>
8995 ts . createTypeParameterDeclaration ( p . name , p . constraint . map ( getTypeNode ) . toUndefined ( ) )
9096 )
9197 )
@@ -145,8 +151,8 @@ const getDataModuleDeclaration = (d: M.Data): ts.ModuleDeclaration => {
145151 ts . createModuleBlock ( [
146152 getInterfaceDeclaration ( URI2HKT , parameters . map ( p => ts . createTypeParameterDeclaration ( p ) ) , [
147153 getPropertySignature (
148- d . introduction . name ,
149- ts . createTypeReferenceNode ( d . introduction . name , parameters . map ( p => ts . createTypeReferenceNode ( p , [ ] ) ) ) ,
154+ d . name ,
155+ ts . createTypeReferenceNode ( d . name , parameters . map ( p => ts . createTypeReferenceNode ( p , [ ] ) ) ) ,
150156 false
151157 )
152158 ] )
@@ -182,7 +188,7 @@ const getMethod = (
182188}
183189
184190const getFoldMethod = ( d : M . Data , c : M . Constructor , name : string , isEager : boolean ) => {
185- const returnTypeParameterName = getFoldReturnTypeParameterName ( d . introduction )
191+ const returnTypeParameterName = getFoldReturnTypeParameterName ( d )
186192 const handlerExpression = ts . createIdentifier ( getFoldHandlerName ( c ) )
187193 const returnExpression =
188194 isNullaryConstructor ( c ) && isEager
@@ -210,19 +216,19 @@ const getDataFptsEncoding = (d: M.Data): AST<Array<ts.Node>> => {
210216 d . constructors . toArray ( ) . map ( c => {
211217 return ts . createTypeReferenceNode (
212218 c . name ,
213- d . introduction . parameters . map ( p => ts . createTypeReferenceNode ( p . name , [ ] ) )
219+ d . parameterDeclarations . map ( p => ts . createTypeReferenceNode ( p . name , [ ] ) )
214220 )
215221 } )
216222 )
217223
218224 const moduleDeclaration = getDataModuleDeclaration ( d )
219225
220- const uriValue = getConstantDeclaration ( 'URI' , ts . createStringLiteral ( d . introduction . name ) )
226+ const uriValue = getConstantDeclaration ( 'URI' , ts . createStringLiteral ( d . name ) )
221227
222228 const uriType = getTypeAliasDeclaration ( 'URI' , ts . createTypeQueryNode ( ts . createIdentifier ( 'URI' ) ) )
223229
224230 const classes = d . constructors . toArray ( ) . map ( c => {
225- const typeParameters = d . introduction . parameters . map ( p => ts . createTypeParameterDeclaration ( p . name ) )
231+ const typeParameters = d . parameterDeclarations . map ( p => ts . createTypeParameterDeclaration ( p . name ) )
226232 const parameters : Array < ts . ParameterDeclaration > = c . members . map ( ( m , position ) => {
227233 return getParameterDeclaration ( getMemberName ( m , position ) , getTypeNode ( m . type ) , true )
228234 } )
@@ -247,12 +253,13 @@ const getDataFptsEncoding = (d: M.Data): AST<Array<ts.Node>> => {
247253
248254 const URI = getPropertyDeclaration ( '_URI' , ts . createTypeReferenceNode ( 'URI' , [ ] ) , undefined , true )
249255
250- // TODO
251- let folds : Array < ts . ClassElement >
252- if ( isEagerFoldSupported ( d ) ) {
253- folds = [ getFoldMethod ( d , c , e . foldName , true ) , getFoldMethod ( d , c , `${ e . foldName } L` , false ) ]
254- } else {
255- folds = [ getFoldMethod ( d , c , e . foldName , false ) ]
256+ let folds : Array < ts . ClassElement > = empty
257+ if ( isSumType ( d ) ) {
258+ if ( isEagerFoldSupported ( d ) ) {
259+ folds = [ getFoldMethod ( d , c , e . foldName , true ) , getFoldMethod ( d , c , `${ e . foldName } L` , false ) ]
260+ } else {
261+ folds = [ getFoldMethod ( d , c , e . foldName , false ) ]
262+ }
256263 }
257264
258265 const members : Array < ts . ClassElement > = [ tag , ...fptsParameters , URI , constructor , ...folds ]
@@ -264,8 +271,8 @@ const getDataFptsEncoding = (d: M.Data): AST<Array<ts.Node>> => {
264271 'value' ,
265272 undefined ,
266273 ts . createTypeReferenceNode (
267- d . introduction . name ,
268- d . introduction . parameters . map ( _ => ts . createTypeReferenceNode ( 'never' , [ ] ) )
274+ d . name ,
275+ d . parameterDeclarations . map ( _ => ts . createTypeReferenceNode ( 'never' , [ ] ) )
269276 ) ,
270277 ts . createNew ( ts . createIdentifier ( c . name ) , undefined , [ ] )
271278 )
@@ -286,9 +293,9 @@ const getDataFptsEncoding = (d: M.Data): AST<Array<ts.Node>> => {
286293 uriValue ,
287294 uriType ,
288295 getTypeAliasDeclaration (
289- d . introduction . name ,
296+ d . name ,
290297 unionType ,
291- d . introduction . parameters . map ( p =>
298+ d . parameterDeclarations . map ( p =>
292299 ts . createTypeParameterDeclaration ( p . name , p . constraint . map ( getTypeNode ) . toUndefined ( ) )
293300 )
294301 ) ,
@@ -298,7 +305,7 @@ const getDataFptsEncoding = (d: M.Data): AST<Array<ts.Node>> => {
298305}
299306
300307const getDataParametersLength = ( d : M . Data ) : number => {
301- return d . introduction . parameters . length
308+ return d . parameterDeclarations . length
302309}
303310
304311const shouldUseLiteralEncoding = ( d : M . Data ) : AST < boolean > => {
@@ -359,12 +366,12 @@ const getParameterDeclaration = (
359366 )
360367}
361368
362- const getLiteralNullaryConstructor = ( c : M . Constructor , introduction : M . Introduction ) : AST < ts . Node > => {
369+ const getLiteralNullaryConstructor = ( c : M . Constructor , d : M . Data ) : AST < ts . Node > => {
363370 return new Reader ( e => {
364371 const name = getFirstLetterLowerCase ( c . name )
365372 const type = ts . createTypeReferenceNode (
366- introduction . name ,
367- introduction . parameters . map ( p =>
373+ d . name ,
374+ d . parameterDeclarations . map ( p =>
368375 p . constraint . map ( c => getTypeNode ( c ) ) . getOrElse ( ts . createKeywordTypeNode ( ts . SyntaxKind . NeverKeyword ) )
369376 )
370377 )
@@ -373,10 +380,10 @@ const getLiteralNullaryConstructor = (c: M.Constructor, introduction: M.Introduc
373380 } )
374381}
375382
376- const getLiteralConstructor = ( c : M . Constructor , introduction : M . Introduction ) : AST < ts . Node > => {
383+ const getLiteralConstructor = ( c : M . Constructor , d : M . Data ) : AST < ts . Node > => {
377384 return new Reader ( e => {
378385 const name = getFirstLetterLowerCase ( c . name )
379- const typeParameters = introduction . parameters . map ( p => {
386+ const typeParameters = d . parameterDeclarations . map ( p => {
380387 return ts . createTypeParameterDeclaration ( p . name , p . constraint . map ( getTypeNode ) . toUndefined ( ) )
381388 } )
382389 const parameters = c . members . map ( ( m , position ) => {
@@ -385,8 +392,8 @@ const getLiteralConstructor = (c: M.Constructor, introduction: M.Introduction):
385392 return getParameterDeclaration ( name , type )
386393 } )
387394 const type = ts . createTypeReferenceNode (
388- introduction . name ,
389- introduction . parameters . map ( p => ts . createTypeReferenceNode ( p . name , [ ] ) )
395+ d . name ,
396+ d . parameterDeclarations . map ( p => ts . createTypeReferenceNode ( p . name , [ ] ) )
390397 )
391398 const body = ts . createBlock ( [
392399 ts . createReturn (
@@ -406,20 +413,20 @@ const getLiteralConstructor = (c: M.Constructor, introduction: M.Introduction):
406413const getConstructorsLiteralEncoding = ( d : M . Data ) : AST < Array < ts . Node > > => {
407414 const constructors = d . constructors . toArray ( ) . map ( c => {
408415 if ( c . members . length === 0 ) {
409- return getLiteralNullaryConstructor ( c , d . introduction )
416+ return getLiteralNullaryConstructor ( c , d )
410417 } else {
411- return getLiteralConstructor ( c , d . introduction )
418+ return getLiteralConstructor ( c , d )
412419 }
413420 } )
414421 return array . sequence ( reader ) ( constructors )
415422}
416423
417- const getFptsNullaryConstructor = ( c : M . Constructor , introduction : M . Introduction ) : AST < ts . Node > => {
424+ const getFptsNullaryConstructor = ( c : M . Constructor , d : M . Data ) : AST < ts . Node > => {
418425 return new Reader ( _ => {
419426 const name = getFirstLetterLowerCase ( c . name )
420427 const type = ts . createTypeReferenceNode (
421- introduction . name ,
422- introduction . parameters . map ( p =>
428+ d . name ,
429+ d . parameterDeclarations . map ( p =>
423430 p . constraint . map ( c => getTypeNode ( c ) ) . getOrElse ( ts . createKeywordTypeNode ( ts . SyntaxKind . NeverKeyword ) )
424431 )
425432 )
@@ -428,10 +435,10 @@ const getFptsNullaryConstructor = (c: M.Constructor, introduction: M.Introductio
428435 } )
429436}
430437
431- const getFptsConstructor = ( c : M . Constructor , introduction : M . Introduction ) : AST < ts . Node > => {
438+ const getFptsConstructor = ( c : M . Constructor , d : M . Data ) : AST < ts . Node > => {
432439 return new Reader ( _ => {
433440 const name = getFirstLetterLowerCase ( c . name )
434- const typeParameters = introduction . parameters . map ( p => {
441+ const typeParameters = d . parameterDeclarations . map ( p => {
435442 return ts . createTypeParameterDeclaration ( p . name , p . constraint . map ( getTypeNode ) . toUndefined ( ) )
436443 } )
437444 const parameters = c . members . map ( ( m , position ) => {
@@ -440,8 +447,8 @@ const getFptsConstructor = (c: M.Constructor, introduction: M.Introduction): AST
440447 return getParameterDeclaration ( name , type )
441448 } )
442449 const type = ts . createTypeReferenceNode (
443- introduction . name ,
444- introduction . parameters . map ( p => ts . createTypeReferenceNode ( p . name , [ ] ) )
450+ d . name ,
451+ d . parameterDeclarations . map ( p => ts . createTypeReferenceNode ( p . name , [ ] ) )
445452 )
446453 const body = ts . createBlock ( [
447454 ts . createReturn (
@@ -461,9 +468,9 @@ const getFptsConstructor = (c: M.Constructor, introduction: M.Introduction): AST
461468const getConstructorsFptsEncoding = ( d : M . Data ) : AST < Array < ts . Node > > => {
462469 const constructors = d . constructors . toArray ( ) . map ( c => {
463470 if ( c . members . length === 0 ) {
464- return getFptsNullaryConstructor ( c , d . introduction )
471+ return getFptsNullaryConstructor ( c , d )
465472 } else {
466- return getFptsConstructor ( c , d . introduction )
473+ return getFptsConstructor ( c , d )
467474 }
468475 } )
469476 return array . sequence ( reader ) ( constructors )
@@ -487,11 +494,11 @@ const isSumType = (d: M.Data): boolean => {
487494 return d . constructors . length ( ) > 1
488495}
489496
490- const getFoldReturnTypeParameterName = ( i : M . Introduction ) : string => {
497+ const getFoldReturnTypeParameterName = ( d : M . Data ) : string => {
491498 const base = 'R'
492499 let candidate = base
493500 let counter = 0
494- while ( i . parameters . findIndex ( ( { name } ) => candidate === name ) !== - 1 ) {
501+ while ( d . parameterDeclarations . findIndex ( ( { name } ) => candidate === name ) !== - 1 ) {
495502 candidate = base + ++ counter
496503 }
497504 return candidate
@@ -506,7 +513,7 @@ const getFoldPositionalHandlers = (
506513 isEager : boolean ,
507514 usedConstructor ?: M . Constructor
508515) : Array < ts . ParameterDeclaration > => {
509- const returnTypeParameterName = getFoldReturnTypeParameterName ( d . introduction )
516+ const returnTypeParameterName = getFoldReturnTypeParameterName ( d )
510517 return d . constructors . toArray ( ) . map ( c => {
511518 const type =
512519 isEager && isNullaryConstructor ( c )
@@ -523,7 +530,7 @@ const getFoldPositionalHandlers = (
523530}
524531
525532const getFoldRecordHandlers = ( d : M . Data , handlersName : string , isEager : boolean ) : Array < ts . ParameterDeclaration > => {
526- const returnTypeParameterName = getFoldReturnTypeParameterName ( d . introduction )
533+ const returnTypeParameterName = getFoldReturnTypeParameterName ( d )
527534 const type = ts . createTypeLiteralNode (
528535 d . constructors . toArray ( ) . map ( c => {
529536 const type =
@@ -597,16 +604,13 @@ const getFold = (d: M.Data, name: string, isEager: boolean): AST<ts.FunctionDecl
597604 const matcheeName = e . matcheeName
598605 const tagName = e . tagName
599606 const handlersStyle = e . handlersStyle
600- const returnTypeParameterName = getFoldReturnTypeParameterName ( d . introduction )
601- const typeParameters = d . introduction . parameters
602- . concat ( M . parameter ( returnTypeParameterName , none ) )
607+ const returnTypeParameterName = getFoldReturnTypeParameterName ( d )
608+ const typeParameters = d . parameterDeclarations
609+ . concat ( M . parameterDeclaration ( returnTypeParameterName , none ) )
603610 . map ( p => ts . createTypeParameterDeclaration ( p . name , p . constraint . map ( getTypeNode ) . toUndefined ( ) ) )
604611 const matchee = getParameterDeclaration (
605612 matcheeName ,
606- ts . createTypeReferenceNode (
607- d . introduction . name ,
608- d . introduction . parameters . map ( p => ts . createTypeReferenceNode ( p . name , [ ] ) )
609- )
613+ ts . createTypeReferenceNode ( d . name , d . parameterDeclarations . map ( p => ts . createTypeReferenceNode ( p . name , [ ] ) ) )
610614 )
611615 const handlers =
612616 handlersStyle . type === 'positional'
0 commit comments