Hone logo
Hone
Problems

Type-Level Parser for Simple Arithmetic Expressions

This challenge asks you to implement a type-level parser in TypeScript that can evaluate simple arithmetic expressions consisting of integers, addition (+), and subtraction (-). Type-level programming allows us to perform computations and validations at compile time, leading to more robust and performant code. This exercise will demonstrate the power of TypeScript's type system for manipulating data and enforcing constraints.

Problem Description

You need to create a type ParseExpr<T> that takes a type T representing a string expression and returns a type representing the result of evaluating that expression. The expression will consist of integers and the operators '+' and '-'. The parser should handle expressions with multiple operations and respect operator precedence (left-to-right). The parser should return a number representing the result of the expression.

Key Requirements:

  • Input: A string expression like "1+2-3" or "4-1+5".
  • Operators: Only '+' and '-' are supported.
  • Operands: Only integers are supported.
  • Output: A number representing the result of the expression.
  • Error Handling: If the input is not a valid expression (e.g., contains invalid characters, unbalanced operators), the type should resolve to never.
  • Type Safety: The entire parsing and evaluation process should be performed at the type level.

Expected Behavior:

  • ParseExpr<"1+2-3"> should resolve to 0.
  • ParseExpr<"4-1+5"> should resolve to 8.
  • ParseExpr<"10"> should resolve to 10.
  • ParseExpr<"2+3+4"> should resolve to 9.
  • ParseExpr<"5-2-1"> should resolve to 2.
  • ParseExpr<"1+a"> should resolve to never.
  • ParseExpr<"1++2"> should resolve to never.

Edge Cases to Consider:

  • Empty string: Should resolve to never.
  • String with only operators: Should resolve to never.
  • Leading/trailing spaces: Should be handled gracefully (ignored).
  • Multiple consecutive operators: Should resolve to never.
  • Non-integer numbers: Should resolve to never.

Examples

Example 1:

Input: "1+2-3"
Output: 0
Explanation: The expression is evaluated from left to right: (1 + 2) - 3 = 3 - 3 = 0.

Example 2:

Input: "4-1+5"
Output: 8
Explanation: The expression is evaluated from left to right: (4 - 1) + 5 = 3 + 5 = 8.

Example 3:

Input: "10"
Output: 10
Explanation: A single number is simply returned as its value.

Example 4:

Input: "2+3+4"
Output: 9
Explanation: Evaluated left to right: (2+3)+4 = 5+4 = 9

Example 5:

Input: "5-2-1"
Output: 2
Explanation: Evaluated left to right: (5-2)-1 = 3-1 = 2

Example 6:

Input: "1+a"
Output: never
Explanation: Invalid character 'a' in the expression.

Constraints

  • The input string will only contain digits (0-9), '+', '-', and potentially spaces.
  • The parser must be implemented using TypeScript's type system, without runtime evaluation.
  • The parser should be reasonably efficient in terms of type checking time (avoiding excessively complex or recursive type definitions that could lead to compilation errors).
  • The parser should handle expressions up to a reasonable length (e.g., 20 characters) without causing excessive type checking time. While there's no strict limit, extremely long expressions might lead to compilation issues.

Notes

  • Consider using conditional types and recursive types to build the parser.
  • You might want to define helper types to represent integers and operators at the type level.
  • Think about how to handle operator precedence (although this problem specifies left-to-right evaluation, understanding precedence is a good exercise).
  • Start with a simple case (e.g., parsing a single addition) and gradually add complexity.
  • Debugging type-level code can be challenging. Use small, testable examples to verify your progress.
  • The goal is to demonstrate type-level computation, not to create a production-ready parser. Focus on clarity and correctness within the constraints of the type system.
Loading editor...
typescript