Box
Box
is a foundational abstraction in F-Box. It encapsulates a single value and provides a functional interface for transforming, combining, and chaining operations.
The Box
abstraction simplifies handling values in a functional programming style. It ensures immutability and composability, making it ideal for scenarios requiring predictable and side-effect-free operations.
Key Features
- Encapsulation: Wraps a value to provide a controlled interface for interactions.
- Immutability: Operations do not alter the original value but produce new
Box
instances.
Creating a Box
To create a Box
, use the static method Box.pack
. This method initializes a Box
instance with a given value.
import { Box } from "f-box-core"
const box = Box.pack(42)console.log(box.getValue()) // Outputs: 42
Supported Operators
The Box
abstraction provides the following operators for working with its encapsulated value. Each operator is an alias for a corresponding method.
<$>
: Alias formap
. Applies a transformation function to the value.<*>
: Alias forapply
. Combines a function in aBox
with a value in anotherBox
.>>=
: Alias forflatMap
. Chains computations that return newBox
instances.
For detailed usage, see API Methods.
API Methods
Box.pack
Box.pack(value: T): Box<T>
Creates a new Box
instance containing the provided value.
const box = Box.pack(42)console.log(box.getValue()) // Outputs: 42
Box.isBox
Box.isBox(value: any): boolean
Checks if a given value is a Box
instance.
import { Box } from "f-box-core"
const box = Box.pack(10)console.log(Box.isBox(box)) // Outputs: trueconsole.log(Box.isBox({})) // Outputs: false
map
map<U>(fn: (value: T) => U): Box<U>
Applies a transformation function to the encapsulated value, returning a new Box
with the result.
Alias: <$>
const box = Box.pack(10)const transformedBox = box["<$>"]((x) => x * 2)console.log(transformedBox.getValue()) // Outputs: 20
// Method callconst transformedBox = box.map((x) => x * 2)console.log(transformedBox.getValue()) // Outputs: 20
apply
apply<A, B>(this: Box<(a: A) => B>, boxValue: Box<A>): Box<B>
Applies a function wrapped in one Box
to a value wrapped in another Box
.
Alias: <*>
const boxFn = Box.pack((x: number) => x + 5)const boxValue = Box.pack(10)const resultBox = boxFn["<*>"](boxValue)console.log(resultBox.getValue()) // Outputs: 15
// Method callconst resultBox = boxFn.apply(boxValue)console.log(resultBox.getValue()) // Outputs: 15
flatMap
flatMap<U>(fn: (value: T) => Box<U>): Box<U>
Applies a function returning a Box
to the value inside this Box
and flattens the result.
Alias: >>=
const box = Box.pack(10)const chainedBox = box[">>="]((x) => Box.pack(x * 2))console.log(chainedBox.getValue()) // Outputs: 20
// Method callconst chainedBox = box.flatMap((x) => Box.pack(x * 2))console.log(chainedBox.getValue()) // Outputs: 20
getValue
getValue(): T
Retrieves the value encapsulated in the Box
.
const box = Box.pack(10)console.log(box.getValue()) // Outputs: 10
Use Cases
Transforming Values
Apply a series of transformations to encapsulated values:
const box = Box.pack(100) ["<$>"]((x) => x / 2) ["<$>"]((x) => x + 10)
console.log(box.getValue()) // Outputs: 60
Applicative Style
Combine multiple Box
instances using the <*>
operator. The function used in this example is curried to enable step-by-step application.
// Pack a curried functionconst box = Box.pack((a: number) => (b: number) => a + b) ["<*>"](Box.pack(10)) ["<*>"](Box.pack(20))
console.log(box.getValue()) // Outputs: 30
Composing Functions
Chain multiple operations into a pipeline:
const box = Box.pack(10) [">>="]((x) => Box.pack(x * 2)) [">>="]((x) => Box.pack(x + 5))
console.log(box.getValue()) // Outputs: 25
Why Use Box?
The Box
abstraction is a lightweight and intuitive tool for functional programming. Its operators and methods provide consistency across all of F-Box’s abstractions, ensuring seamless integration and predictable behavior.
Next Steps
Explore other abstractions built on Box
: