Skip to content

Instantly share code, notes, and snippets.

@mrjacobbloom
Last active October 5, 2020 17:22
Show Gist options
  • Save mrjacobbloom/48eef02fc67437a2a8aa452bfa70af32 to your computer and use it in GitHub Desktop.
Save mrjacobbloom/48eef02fc67437a2a8aa452bfa70af32 to your computer and use it in GitHub Desktop.
/*
* ELIZA
* ELIZA is a simple chatbot developed in the 1960s that acts like a Rogerian psychotherapist
* This is an attempt to port her into the TypeScript type system. By that, I mean all of the
* logic for this chatbot exists in the "types" side of TypeScript and is removed when you
* compile it to JavaScript. This is possible because TypeScript recently added very basic
* support for parsing string literal types (see https://github.com/microsoft/TypeScript/pull/40336)
*
* By Jacob Bloom @mrjacobbloom
* Prompts and responses adapted from here: https://github.com/codeanticode/eliza/blob/master/data/eliza.script
*/
type response = Eliza<"Write your message to ELIZA here">;
// ^^^^^^^^ Hover your mouse over this to see ELIZA's response
type Post<T extends string> =
T extends `${infer start} am ${infer end}` ? `${Post<start>} are ${Post<end>}` :
T extends `${infer start} are ${infer end}` ? `${Post<start>} am ${Post<end>}` :
T extends `${infer start} your ${infer end}` ? `${Post<start>} my ${Post<end>}` :
T extends `${infer start} my ${infer end}` ? `${Post<start>} your ${Post<end>}` :
T extends `${infer start} me${infer end}` ? `${Post<start>} you${Post<end>}` :
T extends `${infer start} you ${infer end}` ? `${Post<start>} me ${Post<end>}` :
T extends `${infer start} myself ${infer end}` ? `${Post<start>} yourself ${Post<end>}` :
T extends `${infer start} yourself ${infer end}` ? `${Post<start>} myself ${Post<end>}` :
T extends `${infer start}I ${infer end}` ? `${Post<start>}you ${Post<end>}` :
T extends `${infer start}I'm ${infer end}` ? `${Post<start>}you are ${Post<end>}` :
T;
type Eliza<T extends string> =
T extends
| 'Write your message to ELIZA here'
? 'How do you do. Please tell me your problem.'
: T extends
| `${infer _start}Sorry${infer _end}`
| `${infer _start}sorry${infer _end}`
| `${infer _start}apologise${infer _end}`
| `${infer _start}apologize${infer _end}`
? 'Please don\'t apologise.'
: T extends
| `${infer _start}I remember ${infer $1}`
? `Do you often think of ${Post<$1>} ?`
: T extends
| `${infer _start}Do you remember ${infer $1}`
| `${infer _start}do you remember ${infer $1}`
? `Did you think I would forget ${Post<$1>} ?`
: T extends
| `${infer _start}If ${infer $1}`
| `${infer _start}if ${infer $1}`
? `Do you think it\'s likely that ${Post<$1>} ?`
: T extends
| `${infer _start}I dreamed ${infer $1}`
? `Really, ${Post<$1>} ?`
: T extends
| `${infer _start}dream${infer _end}`
? 'What does that dream suggest to you ?'
: T extends
| `${infer _start}perhaps${infer _end}`
? 'You don\'t seem quite certain.'
: T extends
| `${infer _start}name${infer _end}`
? 'I am not interested in names.'
: T extends
| `${infer _start}deutsch${infer _end}`
| `${infer _start}Deutsch${infer _end}`
| `${infer _start}francais${infer _end}`
| `${infer _start}Francais${infer _end}`
| `${infer _start}italiano${infer _end}`
| `${infer _start}Italiano${infer _end}`
| `${infer _start}espanol${infer _end}`
| `${infer _start}Espanol${infer _end}`
? 'I speak only English.'
: T extends
| `${infer _start}Hello${infer _end}`
| `${infer _start}hello${infer _end}`
? 'How do you do. Please state your problem.'
: T extends
| `${infer _start}Computer${infer _end}`
| `${infer _start}computer${infer _end}`
? 'Do computers worry you ?'
: T extends
| `${infer _start}I desire ${infer $1}`
| `${infer _start}I want ${infer $1}`
| `${infer _start}I need ${infer $1}`
? `What would it mean to you if you got ${Post<$1>} ?`
: T extends
| `${infer _start}I am${infer _mid}sad${infer _end}`
? 'I am sorry to hear that you are sad.'
: T extends
| `${infer _start}I am${infer _mid}unhappy${infer _end}`
? 'I am sorry to hear that you are unhappy.'
: T extends
| `${infer _start}I am${infer _mid}depressed${infer _end}`
? 'I am sorry to hear that you are depressed.'
: T extends
| `${infer _start}I am${infer _mid}sick${infer _end}`
? 'I am sorry to hear that you are sick.'
: T extends
| `${infer _start}I am${infer _mid}happy${infer _end}`
? 'How have I helped you to be happy ?'
: T extends
| `${infer _start}I am${infer _mid}elated${infer _end}`
? 'How have I helped you to be elated ?'
: T extends
| `${infer _start}I am${infer _mid}glad${infer _end}`
? 'How have I helped you to be glad ?'
: T extends
| `${infer _start}I am${infer _mid}better${infer _end}`
? 'How have I helped you to be better ?'
: T extends
| `${infer _start}I believe${infer _mid}I${infer _end}`
| `${infer _start}I feel${infer _mid}I${infer _end}`
| `${infer _start}I think${infer _mid}I${infer _end}`
| `${infer _start}I wish${infer _mid}I${infer _end}`
? 'Do you really think so ?'
: T extends
| `${infer _start}I cannot ${infer $1}`
| `${infer _start}I can't ${infer $1}`
? `How do you think that you can't ${Post<$1>} ?`
: T extends
| `${infer _start}I don't ${infer $1}`
? `Don't you really ${Post<$1>} ?`
: T extends
| `${infer _start}do I feel${infer _end}`
| `${infer _start}Do I feel${infer _end}`
? 'Tell me more about such feelings.'
: T extends
| `${infer _start}I ${infer $1} you${infer _end}`
? `Perhaps in your fantasies we ${Post<$1>} each other.`
: T extends
| `${infer _start}you are ${infer $1}`
| `${infer _start}You are ${infer $1}`
? `What makes you think I am ${Post<$1>} ?`
: T extends
| `${infer _start}You ${infer $1} me${infer _end}`
| `${infer _start}you ${infer $1} me${infer _end}`
? `Why do you think I ${Post<$1>} you ?`
: T extends
| `${infer _start}Yes${infer _end}`
| `${infer _start}yes${infer _end}`
? 'You seem to be quite positive.'
: T extends
| `${infer _start}No${infer _end}`
| `${infer _start}no${infer _end}`
? 'Are you saying no just to be negative?'
: T extends
| `${infer _start}my family${infer _end}`
| `${infer _start}My family${infer _end}`
| `${infer _start}my mother${infer _end}`
| `${infer _start}My mother${infer _end}`
| `${infer _start}my mom${infer _end}`
| `${infer _start}My mom${infer _end}`
| `${infer _start}my father${infer _end}`
| `${infer _start}My father${infer _end}`
| `${infer _start}my dad${infer _end}`
| `${infer _start}My dad${infer _end}`
| `${infer _start}my sister${infer _end}`
| `${infer _start}My sister${infer _end}`
| `${infer _start}my brother${infer _end}`
| `${infer _start}My brother${infer _end}`
| `${infer _start}my wife${infer _end}`
| `${infer _start}My wife${infer _end}`
| `${infer _start}my husband${infer _end}`
| `${infer _start}My husband${infer _end}`
| `${infer _start}my children${infer _end}`
| `${infer _start}My children${infer _end}`
| `${infer _start}my child${infer _end}`
| `${infer _start}My child${infer _end}`
? 'Tell me more about your family.'
: T extends
| `${infer _start}my ${infer $1}`
| `${infer _start}My ${infer $1}`
? `Your ${Post<$1>} ?`
: T extends
| `${infer _start}can you ${infer $1}`
| `${infer _start}Can you ${infer $1}`
? `You believe I can ${Post<$1>} don't you ?`
: T extends
| `${infer _start}can I ${infer $1}`
| `${infer _start}Can I ${infer $1}`
? `Whether or not you can ${Post<$1>} depends on you more than me.`
: T extends
| `${infer _start}What${infer _end}`
| `${infer _start}what${infer _end}`
? 'Why do you ask ?'
: T extends
| `${infer _start}Because${infer _end}`
| `${infer _start}because${infer _end}`
? 'Is that the real reason ?'
: T extends
| `${infer _start}why don't you ${infer $1}` // Probably inaccessible, move above "you"
| `${infer _start}Why don't you ${infer $1}`
? `Do you believe I don't ${Post<$1>} ?`
: T extends
| `${infer _start}why can't I ${infer $1}`
| `${infer _start}Why can't I ${infer $1}`
? `Do you think you should be able to ${Post<$1>} ?`
// @todo why -> goto what
: T extends
| `${infer _start}everyone ${infer $1}`
| `${infer _start}Everyone ${infer $1}`
| `${infer _start}everybody ${infer $1}`
| `${infer _start}Everybody ${infer $1}`
| `${infer _start}nobody ${infer $1}`
| `${infer _start}Nobody ${infer $1}`
| `${infer _start}noone ${infer $1}`
| `${infer _start}Noone ${infer $1}`
| `${infer _start}no one ${infer $1}`
| `${infer _start}No one ${infer $1}`
? `Realy, ${Post<$1>} ?`
: T extends
| `${infer _start}always${infer _end}`
| `${infer _start}Always${infer _end}`
? 'Can you think of a specific example ?'
: T extends
| `${infer _start}alike${infer _end}`
| `${infer _start}Alike${infer _end}`
| `${infer _start}be like${infer _end}`
| `${infer _start}Be like${infer _end}`
| `${infer _start}am like${infer _end}`
| `${infer _start}Am like${infer _end}`
| `${infer _start}is like${infer _end}`
| `${infer _start}Is like${infer _end}`
| `${infer _start}are like${infer _end}`
| `${infer _start}Are like${infer _end}`
| `${infer _start}was like${infer _end}`
| `${infer _start}Was like${infer _end}`
| `${infer _start}you remind me of${infer _end}`
| `${infer _start}You remind me of${infer _end}`
? 'In what way ?'
// All interesting responses need to go above these
: T extends
| `${infer _start}I am ${infer $1}`
? `Is it because you are ${Post<$1>} that you came to me ?`
: T extends
| `${infer _start}am I ${infer $1}`
| `${infer _start}Am I ${infer $1}`
? `Do you believe you are ${Post<$1>} ?`
: T extends
| `${infer _start} am ${infer _end}`
? 'I don\'t understand that.'
: T extends
| `${infer _start}are you ${infer $1}`
| `${infer _start}Are you ${infer $1}`
? `Why are you interested in whether I am ${Post<$1>} or not ?`
: T extends
| `${infer _start} are ${infer $1}`
? `Did you think they might not be ${Post<$1>} ?`
: T extends
| `${infer _start}your ${infer $1}`
| `${infer _start}Your ${infer $1}`
? `Why are you concerned over my ${Post<$1>} ?`
: T extends
| `${infer _start}was I ${infer $1}`
| `${infer _start}Was I ${infer $1}`
? `What if you were ${Post<$1>} ?`
: T extends
| `${infer _start}I was${infer _end}`
? 'Were you really ?'
: T extends
| `${infer _start}was you ${infer $1}` // what does this mean?? As in "the first thing I thought of was you"?
| `${infer _start}Was you ${infer $1}`
? `Would you like to believe I was ${Post<$1>} ?`
: T extends
| `${infer _start}You${infer _end}`
| `${infer _start}you${infer _end}`
| `${infer _start}I believe${infer _mid}you${infer _end}`
| `${infer _start}I feel${infer _mid}you${infer _end}`
| `${infer _start}I think${infer _mid}you${infer _end}`
| `${infer _start}I wish${infer _mid}you${infer _end}`
? 'We were discussing you -- not me.'
: T extends
| `${infer _start}I${infer _end}`
? `You say ${Post<T>} ?`
: 'I\'m not sure I understand you fully.';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment