bytes

package
v2.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 22, 2025 License: Apache-2.0 Imports: 3 Imported by: 0

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

View Source
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

func Size(as []byte) int

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

func ToString(a []byte) string

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL