Reference · Utilities
Magma
Binary operations without constraints. The most basic algebraic structure - just a way to combine two values.
Core API
| Function | Signature | Description |
|---|---|---|
MakeMagma | func MakeMagma[A any](func(A, A) A) Magma[A] | Create magma from function |
Usage Examples
Basic Usage
basic.go
import Mg "github.com/IBM/fp-go/v2/magma"
// Create magma for averaging
avgMagma := Mg.MakeMagma(func(a, b float64) float64 {
return (a + b) / 2
})
result := avgMagma.Concat(10, 20)
// 15.0
Conflict Resolution Strategies
strategies.go
// Last-wins strategy
lastWins := Mg.MakeMagma(func(a, b T) T {
return b
})
// First-wins strategy
firstWins := Mg.MakeMagma(func(a, b T) T {
return a
})
// Max strategy
maxMagma := Mg.MakeMagma(func(a, b int) int {
if a > b { return a }
return b
})
// Min strategy
minMagma := Mg.MakeMagma(func(a, b int) int {
if a < b { return a }
return b
})
Custom Merging
merge.go
type User struct {
ID int
Name string
UpdatedAt time.Time
}
// Merge users (keep most recent)
userMagma := Mg.MakeMagma(func(a, b User) User {
if a.UpdatedAt.After(b.UpdatedAt) {
return a
}
return b
})
merged := userMagma.Concat(oldUser, newUser)
// Returns the user with the later UpdatedAt
Array Merging
arrays.go
// Concatenate arrays
appendMagma := Mg.MakeMagma(func(a, b []int) []int {
return append(a, b...)
})
result := appendMagma.Concat([]int{1, 2}, []int{3, 4})
// []int{1, 2, 3, 4}
// Union (deduplicate)
unionMagma := Mg.MakeMagma(func(a, b []int) []int {
seen := make(map[int]bool)
result := make([]int, 0)
for _, v := range append(a, b...) {
if !seen[v] {
seen[v] = true
result = append(result, v)
}
}
return result
})
Record Conversion
record.go
import R "github.com/IBM/fp-go/v2/record"
// Use with FromArray for duplicate key handling
entries := []T.Tuple2[string, int]{
T.MakeTuple2("a", 1),
T.MakeTuple2("b", 2),
T.MakeTuple2("a", 10), // Duplicate
}
// Sum duplicates
sumMagma := Mg.MakeMagma(func(x, y int) int { return x + y })
m := R.FromArray(sumMagma)(entries)
// map[string]int{"a": 11, "b": 2}
Common Patterns
Configuration Merging
config.go
type Config struct {
Host string
Port int
Timeout int
}
// Merge configs (right wins for non-zero values)
configMagma := Mg.MakeMagma(func(a, b Config) Config {
return Config{
Host: if b.Host != "" { b.Host } else { a.Host },
Port: if b.Port != 0 { b.Port } else { a.Port },
Timeout: if b.Timeout != 0 { b.Timeout } else { a.Timeout },
}
})
Magma vs Semigroup: Magma doesn't require associativity. Use Magma when the order of operations matters (like averaging), and Semigroup when it doesn't (like addition).
Use Cases: Magma is perfect for:
- Conflict resolution strategies
- Custom merge logic
- Non-associative operations
- Building blocks for more complex structures