Hone logo
Hone
Problems

Scott Encoding in TypeScript

Scott encoding is a technique used in functional programming to represent data types with sum types (also known as tagged unions or discriminated unions) in a type-safe manner. It allows you to represent values that can be one of several distinct types, each identified by a unique tag. This challenge asks you to implement the core types and functions necessary to work with Scott encodings in TypeScript, enabling you to represent and manipulate data with greater type safety and clarity.

Problem Description

The goal is to create a system for representing and working with Scott encodings in TypeScript. This involves defining a base Scott type and then creating specific Scott encoding types for primitive types like number, string, and boolean. You'll also need to implement a function to "unwrap" a Scott encoding, extracting the underlying value based on its tag. The system should be type-safe, ensuring that you can only access the underlying value when the correct tag is present.

Key Requirements:

  • Base Scott Type: Define a base Scott type that includes a tag property (string) and a value property (any).
  • Specific Scott Encoding Types: Create Scott encoding types for NumberScott, StringScott, and BooleanScott. These types should inherit from Scott and have their respective value types (number, string, boolean).
  • unwrap Function: Implement a function unwrap<T>(scott: Scott): T | undefined that takes a Scott value as input and returns the underlying value if the tag matches the expected tag. If the tag doesn't match, it should return undefined.
  • Type Safety: The unwrap function should be type-safe, meaning that the TypeScript compiler should enforce that you're only unwrapping a value to the correct type.

Expected Behavior:

The unwrap function should correctly identify the tag of a Scott value and return the corresponding value. If the tag is incorrect, it should return undefined. The type system should prevent you from attempting to unwrap a NumberScott as a StringScott, for example.

Edge Cases to Consider:

  • What happens if the input is not a Scott type at all? (While not strictly required, consider how you might handle this gracefully).
  • How do you ensure that the tags are unique and consistent across different Scott encoding types? (This is implicitly handled by the specific type definitions).
  • What happens if the value property is null or undefined? (The code should handle this without errors).

Examples

Example 1:

Input: const numScott: NumberScott = { tag: 'number', value: 123 };
Output: unwrap(numScott) // 123
Explanation: The tag 'number' matches the expected tag for a NumberScott, so the value 123 is returned.

Example 2:

Input: const strScott: StringScott = { tag: 'string', value: 'hello' };
Output: unwrap(strScott) // 'hello'
Explanation: The tag 'string' matches the expected tag for a StringScott, so the value 'hello' is returned.

Example 3:

Input: const boolScott: BooleanScott = { tag: 'boolean', value: true };
Output: unwrap(boolScott) // true
Explanation: The tag 'boolean' matches the expected tag for a BooleanScott, so the value true is returned.

Example 4:

Input: const mixedScott: Scott = { tag: 'number', value: 'wrong type' };
Output: unwrap(mixedScott) // undefined
Explanation: Although the tag is 'number', the value is not a number. The unwrap function should still return undefined.

Constraints

  • The tag property of the Scott type must be a string.
  • The unwrap function must be generic, allowing it to unwrap to any type.
  • The code must be written in valid TypeScript.
  • The solution should be reasonably efficient (avoid unnecessary iterations or complex logic).

Notes

Consider using discriminated unions to enforce type safety. The tag property acts as the discriminator. Think about how to leverage TypeScript's type system to ensure that the unwrap function only returns the correct type based on the tag. You don't need to handle invalid Scott types explicitly; the type system should provide sufficient protection.

Loading editor...
typescript