Documentation
¶
Overview ¶
Package bytes provides functional programming utilities for working with byte slices.
This package offers algebraic structures (Monoid, Ord) and utility functions for byte slice operations in a functional style.
Monoid ¶
The Monoid instance for byte slices combines them through concatenation, with an empty byte slice as the identity element.
Example:
import "github.com/IBM/fp-go/v2/bytes"
// Concatenate byte slices
result := bytes.Monoid.Concat([]byte("Hello"), []byte(" World"))
// result: []byte("Hello World")
// Identity element
empty := bytes.Empty() // []byte{}
ConcatAll ¶
Efficiently concatenates multiple byte slices into a single slice:
import "github.com/IBM/fp-go/v2/bytes"
result := bytes.ConcatAll(
[]byte("Hello"),
[]byte(" "),
[]byte("World"),
)
// result: []byte("Hello World")
Ordering ¶
The Ord instance provides lexicographic ordering for byte slices:
import "github.com/IBM/fp-go/v2/bytes"
cmp := bytes.Ord.Compare([]byte("abc"), []byte("abd"))
// cmp: -1 (abc < abd)
equal := bytes.Ord.Equals([]byte("test"), []byte("test"))
// equal: true
Utility Functions ¶
The package provides several utility functions:
// Get empty byte slice
empty := bytes.Empty() // []byte{}
// Convert to string
str := bytes.ToString([]byte("hello")) // "hello"
// Get size
size := bytes.Size([]byte("hello")) // 5
Use Cases ¶
The bytes package is particularly useful for:
- Building byte buffers functionally
- Combining multiple byte slices efficiently
- Comparing byte slices lexicographically
- Working with binary data in a functional style
Example - Building a Protocol Message ¶
import (
"github.com/IBM/fp-go/v2/bytes"
"encoding/binary"
)
// Build a simple protocol message
header := []byte{0x01, 0x02}
length := make([]byte, 4)
binary.BigEndian.PutUint32(length, 100)
payload := []byte("data")
message := bytes.ConcatAll(header, length, payload)
Example - Sorting Byte Slices ¶
import (
"github.com/IBM/fp-go/v2/array"
"github.com/IBM/fp-go/v2/bytes"
)
data := [][]byte{
[]byte("zebra"),
[]byte("apple"),
[]byte("mango"),
}
sorted := array.Sort(bytes.Ord)(data)
// sorted: [[]byte("apple"), []byte("mango"), []byte("zebra")]
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // Monoid is the Monoid instance for byte slices. // // This Monoid combines byte slices through concatenation, with an empty // byte slice as the identity element. It satisfies the monoid laws: // // Identity laws: // - Monoid.Concat(Monoid.Empty(), x) == x (left identity) // - Monoid.Concat(x, Monoid.Empty()) == x (right identity) // // Associativity law: // - Monoid.Concat(Monoid.Concat(a, b), c) == Monoid.Concat(a, Monoid.Concat(b, c)) // // Operations: // - Empty(): Returns an empty byte slice []byte{} // - Concat(a, b []byte): Concatenates two byte slices // // Example - Basic concatenation: // // result := Monoid.Concat([]byte("Hello"), []byte(" World")) // // result: []byte("Hello World") // // Example - Identity element: // // empty := Monoid.Empty() // data := []byte("test") // result1 := Monoid.Concat(empty, data) // []byte("test") // result2 := Monoid.Concat(data, empty) // []byte("test") // // Example - Building byte buffers: // // buffer := Monoid.Empty() // buffer = Monoid.Concat(buffer, []byte("Line 1\n")) // buffer = Monoid.Concat(buffer, []byte("Line 2\n")) // buffer = Monoid.Concat(buffer, []byte("Line 3\n")) // // Example - Associativity: // // a := []byte("a") // b := []byte("b") // c := []byte("c") // left := Monoid.Concat(Monoid.Concat(a, b), c) // []byte("abc") // right := Monoid.Concat(a, Monoid.Concat(b, c)) // []byte("abc") // // left == right // // See also: // - ConcatAll: For concatenating multiple byte slices at once // - Empty(): Convenience function for getting empty byte slice Monoid = A.Monoid[byte]() // ConcatAll efficiently concatenates multiple byte slices into a single slice. // // This function takes a variadic number of byte slices and combines them // into a single byte slice. It pre-allocates the exact amount of memory // needed, making it more efficient than repeated concatenation. // // Parameters: // - slices: Zero or more byte slices to concatenate // // Returns: // - A new byte slice containing all input slices concatenated in order // // Performance: // // ConcatAll is more efficient than using Monoid.Concat repeatedly because // it calculates the total size upfront and allocates memory once, avoiding // multiple allocations and copies. // // Example - Basic usage: // // result := ConcatAll( // []byte("Hello"), // []byte(" "), // []byte("World"), // ) // // result: []byte("Hello World") // // Example - Empty input: // // result := ConcatAll() // // result: []byte{} // // Example - Single slice: // // result := ConcatAll([]byte("test")) // // result: []byte("test") // // Example - Building protocol messages: // // import "encoding/binary" // // header := []byte{0x01, 0x02} // length := make([]byte, 4) // binary.BigEndian.PutUint32(length, 100) // payload := []byte("data") // footer := []byte{0xFF} // // message := ConcatAll(header, length, payload, footer) // // Example - With empty slices: // // result := ConcatAll( // []byte("a"), // []byte{}, // []byte("b"), // []byte{}, // []byte("c"), // ) // // result: []byte("abc") // // Example - Building CSV line: // // fields := [][]byte{ // []byte("John"), // []byte("Doe"), // []byte("30"), // } // separator := []byte(",") // // // Interleave fields with separators // parts := [][]byte{ // fields[0], separator, // fields[1], separator, // fields[2], // } // line := ConcatAll(parts...) // // line: []byte("John,Doe,30") // // See also: // - Monoid.Concat: For concatenating exactly two byte slices // - bytes.Join: Standard library function for joining with separator ConcatAll = A.ArrayConcatAll[byte] // Ord is the Ord instance for byte slices providing lexicographic ordering. // // This Ord instance compares byte slices lexicographically (dictionary order), // comparing bytes from left to right until a difference is found or one slice // ends. It uses the standard library's bytes.Compare and bytes.Equal functions. // // Comparison rules: // - Compares byte-by-byte from left to right // - First differing byte determines the order // - Shorter slice is less than longer slice if all bytes match // - Empty slice is less than any non-empty slice // // Operations: // - Compare(a, b []byte) int: Returns -1 if a < b, 0 if a == b, 1 if a > b // - Equals(a, b []byte) bool: Returns true if slices are equal // // Example - Basic comparison: // // cmp := Ord.Compare([]byte("abc"), []byte("abd")) // // cmp: -1 (abc < abd) // // cmp = Ord.Compare([]byte("xyz"), []byte("abc")) // // cmp: 1 (xyz > abc) // // cmp = Ord.Compare([]byte("test"), []byte("test")) // // cmp: 0 (equal) // // Example - Length differences: // // cmp := Ord.Compare([]byte("ab"), []byte("abc")) // // cmp: -1 (shorter is less) // // cmp = Ord.Compare([]byte("abc"), []byte("ab")) // // cmp: 1 (longer is greater) // // Example - Empty slices: // // cmp := Ord.Compare([]byte{}, []byte("a")) // // cmp: -1 (empty is less) // // cmp = Ord.Compare([]byte{}, []byte{}) // // cmp: 0 (both empty) // // Example - Equality check: // // equal := Ord.Equals([]byte("test"), []byte("test")) // // equal: true // // equal = Ord.Equals([]byte("test"), []byte("Test")) // // equal: false (case-sensitive) // // Example - Sorting byte slices: // // import "github.com/IBM/fp-go/v2/array" // // data := [][]byte{ // []byte("zebra"), // []byte("apple"), // []byte("mango"), // } // // sorted := array.Sort(Ord)(data) // // sorted: [[]byte("apple"), []byte("mango"), []byte("zebra")] // // Example - Binary data comparison: // // cmp := Ord.Compare([]byte{0x01, 0x02}, []byte{0x01, 0x03}) // // cmp: -1 (0x02 < 0x03) // // Example - Finding minimum: // // import O "github.com/IBM/fp-go/v2/ord" // // a := []byte("xyz") // b := []byte("abc") // min := O.Min(Ord)(a, b) // // min: []byte("abc") // // See also: // - bytes.Compare: Standard library comparison function // - bytes.Equal: Standard library equality function // - array.Sort: For sorting slices using an Ord instance Ord = O.MakeOrd(bytes.Compare, bytes.Equal) )
Functions ¶
func Empty ¶
func Empty() []byte
Empty returns an empty byte slice.
This function returns the identity element for the byte slice Monoid, which is an empty byte slice. It's useful as a starting point for building byte slices or as a default value.
Returns:
- An empty byte slice ([]byte{})
Properties:
- Empty() is the identity element for Monoid.Concat
- Monoid.Concat(Empty(), x) == x
- Monoid.Concat(x, Empty()) == x
Example - Basic usage:
empty := Empty() fmt.Println(len(empty)) // 0
Example - As identity element:
data := []byte("hello")
result1 := Monoid.Concat(Empty(), data) // []byte("hello")
result2 := Monoid.Concat(data, Empty()) // []byte("hello")
Example - Building byte slices:
// Start with empty and build up
buffer := Empty()
buffer = Monoid.Concat(buffer, []byte("Hello"))
buffer = Monoid.Concat(buffer, []byte(" "))
buffer = Monoid.Concat(buffer, []byte("World"))
// buffer: []byte("Hello World")
See also:
- Monoid.Empty(): Alternative way to get empty byte slice
- ConcatAll(): For concatenating multiple byte slices
Example ¶
Example tests
empty := Empty() println(len(empty)) // 0
func Size ¶
Size returns the number of bytes in a byte slice.
This function returns the length of the byte slice, which is the number of bytes it contains. This is equivalent to len(as) but provided as a named function for use in functional composition.
Parameters:
- as: The byte slice to measure
Returns:
- The number of bytes in the slice
Example - Basic usage:
data := []byte("hello")
size := Size(data)
fmt.Println(size) // 5
Example - Empty slice:
empty := Empty() size := Size(empty) fmt.Println(size) // 0
Example - Binary data:
binary := []byte{0x01, 0x02, 0x03, 0x04}
size := Size(binary)
fmt.Println(size) // 4
Example - UTF-8 encoded text:
// Note: Size returns byte count, not character count
utf8 := []byte("Hello, 世界")
byteCount := Size(utf8)
fmt.Println(byteCount) // 13 (not 9 characters)
Example - Using in functional composition:
import "github.com/IBM/fp-go/v2/array"
slices := [][]byte{
[]byte("a"),
[]byte("bb"),
[]byte("ccc"),
}
// Map to get sizes
sizes := array.Map(Size)(slices)
// sizes: []int{1, 2, 3}
Example - Checking if slice is empty:
data := []byte("test")
isEmpty := Size(data) == 0
fmt.Println(isEmpty) // false
See also:
- len(): Built-in function for getting slice length
- ToString(): For converting byte slice to string
Example ¶
size := Size([]byte("hello"))
println(size) // 5
func ToString ¶
ToString converts a byte slice to a string.
This function performs a direct conversion from []byte to string. The conversion creates a new string with a copy of the byte data.
Parameters:
- a: The byte slice to convert
Returns:
- A string containing the same data as the byte slice
Performance Note:
This conversion allocates a new string. For performance-critical code that needs to avoid allocations, consider using unsafe.String (Go 1.20+) or working directly with byte slices.
Example - Basic conversion:
bytes := []byte("hello")
str := ToString(bytes)
fmt.Println(str) // "hello"
Example - Converting binary data:
// ASCII codes for "Hello"
data := []byte{0x48, 0x65, 0x6c, 0x6c, 0x6f}
str := ToString(data)
fmt.Println(str) // "Hello"
Example - Empty byte slice:
empty := Empty() str := ToString(empty) fmt.Println(str == "") // true
Example - UTF-8 encoded text:
utf8Bytes := []byte("Hello, 世界")
str := ToString(utf8Bytes)
fmt.Println(str) // "Hello, 世界"
Example - Round-trip conversion:
original := "test string" bytes := []byte(original) result := ToString(bytes) fmt.Println(original == result) // true
See also:
- []byte(string): For converting string to byte slice
- Size(): For getting the length of a byte slice
Example ¶
str := ToString([]byte("hello"))
println(str) // hello
Types ¶
This section is empty.