Your first project with Yukigo
In this introductory guide you will learn to use Yukigo to build a small command line REPL for Haskell.
Setup
First, let's make a NodeJS project
npm init -yNow let's install yukigo and yukigo-haskell-parser
$ npm install yukigo yukigo-haskell-parser$ yarn add yukigo yukigo-haskell-parserCreate an index.js file in the folder, and import YukigoHaskellParser and Interpreter
import { YukigoHaskellParser } from "yukigo-haskell-parser";
import { Interpreter } from "yukigo";Basic Loop (Read-Print-Loop)
Let's make a loop that waits for user input, logs it to the console, and breaks if user inputs exit.
In NodeJS we prompt the user for input using the readline module
import { YukigoHaskellParser } from "yukigo-haskell-parser";
import { Interpreter } from "yukigo";
import readline from "readline";
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
var readLoop = function () {
rl.question('$', function (input) {
if (input == 'exit')
return rl.close();
console.log(input);
readLoop();
});
};
readLoop()Execute the code with node . and you should be able to send an input and get it echoed back
$ Hello!
Hello!Evaluation and Basic Error Handling
Now, lets integrate Yukigo. Lets instantiate the parser and the interpreter before our readLoop function:
const parser = new YukigoHaskellParser();
const prelude = parser.parse("")
const interpreter = new Interpreter(prelude, { lazyLoading: true });The loop should Read the input, Evaluate it, and then Print the result. Let's update the readLoop function to achieve this:
var readLoop = function () {
rl.question("$ ", function (input) {
if (input == "exit") return rl.close();
try {
const expr = parser.parseExpression(input);
const result = interpreter.evaluate(expr);
console.log(result);
} catch (error) {
console.log(error);
}
readLoop();
});
};When we run it, we can do things like:
$ 2 + 2
4
$ map (\x -> x * 2) [1, 2, 3]
[ 2, 4, 6 ]The final code looks like this:
import { YukigoHaskellParser } from "yukigo-haskell-parser";
import { Interpreter } from "yukigo";
import readline from "readline";
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const parser = new YukigoHaskellParser();
const prelude = parser.parse("")
const interpreter = new Interpreter(prelude, { lazyLoading: true });
var readLoop = function () {
rl.question("$ ", function (input) {
if (input == "exit") return rl.close();
try {
const expr = parser.parseExpression(input);
const result = interpreter.evaluate(expr);
console.log(result);
} catch (error) {
console.log(error);
}
readLoop();
});
};
readLoop();Conclusion
And it's done!
In a couple of lines you have built a simple Haskell REPL in NodeJS. You can extend this implementation with better error handling, REPL commands with a certain prefix, context loading from a file, and more features.