Hone logo
Hone
Problems

Type-Level Compiler for Simple Arithmetic Expressions

This challenge asks you to implement a rudimentary type-level compiler in TypeScript. Type-level programming allows you to perform computations and logic at compile time, enabling powerful type safety and optimization. You'll be building a system that can evaluate simple arithmetic expressions (addition and subtraction) represented as TypeScript types.

Problem Description

You need to create a type-level compiler that can evaluate arithmetic expressions consisting of numbers, addition (+), and subtraction (-) operations. The expressions will be represented as tuples of numbers and operators. The compiler should reduce the expression to a single number representing the result of the calculation.

What needs to be achieved:

  • Define a type Expression to represent the arithmetic expression as a tuple. The tuple will contain numbers (represented as number) and operators (represented as 'add' or 'subtract').
  • Create a type Evaluate<T extends Expression> that takes an Expression tuple T and returns a number representing the evaluated result.
  • The evaluation should follow standard arithmetic precedence (left-to-right).

Key Requirements:

  • The compiler must handle addition and subtraction correctly.
  • The compiler must handle multiple operations in a sequence.
  • The compiler must be purely type-level; no runtime execution is allowed.
  • The compiler should be robust and handle invalid expressions gracefully (though error handling beyond returning never is not required).

Expected Behavior:

The Evaluate type should produce the correct numerical result based on the input expression.

Edge Cases to Consider:

  • Empty expressions (should return 0).
  • Expressions with only a single number (should return that number).
  • Expressions with consecutive operators (e.g., [1, 'add', 2, 'subtract', 3]).
  • Expressions with negative numbers.

Examples

Example 1:

type Expression1 = [1, 'add', 2, 'subtract', 3];
type Result1 = Evaluate<Expression1>; // Expected: 0

Explanation: 1 + 2 - 3 = 0

Example 2:

type Expression2 = [5, 'add', 3];
type Result2 = Evaluate<Expression2>; // Expected: 8

Explanation: 5 + 3 = 8

Example 3:

type Expression3 = [10, 'subtract', 5, 'subtract', 2];
type Result3 = Evaluate<Expression3>; // Expected: 3

Explanation: 10 - 5 - 2 = 3

Example 4:

type Expression4 = [10];
type Result4 = Evaluate<Expression4>; // Expected: 10

Explanation: Single number expression.

Example 5:

type Expression5 = [];
type Result5 = Evaluate<Expression5>; // Expected: 0

Explanation: Empty expression.

Constraints

  • The input Expression will only contain numbers of type number and operators of type 'add' or 'subtract'.
  • The expression will be a valid sequence of numbers and operators. No validation of the expression's structure is required beyond ensuring the correct types are present.
  • Performance is not a primary concern; the focus is on correctness and type safety. The compiler should be reasonably efficient for expressions of moderate length (up to 10 elements).
  • The result must be a number.

Notes

  • You'll likely need to use conditional types and recursion to implement the Evaluate type.
  • Consider using helper types to simplify the logic. For example, a type to extract the first element of a tuple.
  • Think about how to handle the base cases (empty expression, single number) and the recursive step (evaluating a sub-expression).
  • This is a challenging problem that requires a good understanding of TypeScript's type system. Start with a simple case and gradually build up the complexity. Don't be afraid to experiment and refactor your code.
  • The goal is to perform the calculation entirely at the type level, without any runtime code.
Loading editor...
typescript