1
0
mirror of https://github.com/IBM/fp-go.git synced 2025-11-23 22:14:53 +02:00
Files
fp-go/v2/magma/doc.go
Carsten Leue 3385c705dc Implement v2 using type aliases (#141)
* fix: initial checkin of v2

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: slowly migrate IO

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: migrate MonadTraverseArray and TraverseArray

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: migrate traversal

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: complete migration of IO

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: migrate ioeither

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: refactorY

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: next step in migration

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: adjust IO generation code

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: get rid of more IO methods

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: get rid of more IO

* fix: convert iooption

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: convert reader

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: convert a bit of reader

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: new build script

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: cleanup

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: reformat

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: simplify

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: some cleanup

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: adjust Pair to Haskell semantic

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: documentation and testcases

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: some performance optimizations

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: remove coverage

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

* fix: better doc

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>

---------

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
2025-11-06 09:27:00 +01:00

247 lines
6.2 KiB
Go

// Copyright (c) 2023 - 2025 IBM Corp.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
Package magma provides the Magma algebraic structure.
# Overview
A Magma is the most basic algebraic structure in abstract algebra. It consists
of a set equipped with a single binary operation (Concat) that combines two
elements to produce another element of the same type. Unlike more constrained
structures like Semigroup or Monoid, a Magma's operation doesn't need to be
associative or have an identity element.
The Magma interface:
type Magma[A any] interface {
Concat(x A, y A) A
}
This simple structure serves as the foundation for more complex algebraic
structures in the type class hierarchy:
- Magma (no laws)
- Semigroup (adds associativity)
- Monoid (adds identity element)
# Basic Usage
Creating and using magmas:
// Create a magma for integer addition
addMagma := magma.MakeMagma(func(a, b int) int {
return a + b
})
result := addMagma.Concat(5, 3)
// result is 8
// Create a magma for string concatenation
stringMagma := magma.MakeMagma(func(a, b string) string {
return a + b
})
result := stringMagma.Concat("Hello", " World")
// result is "Hello World"
# Built-in Magmas
The package provides several pre-defined magmas:
First - Always returns the first argument:
m := magma.First[int]()
result := m.Concat(1, 2)
// result is 1
Second - Always returns the second argument:
m := magma.Second[int]()
result := m.Concat(1, 2)
// result is 2
# Transforming Magmas
Reverse - Swaps the order of arguments:
addMagma := magma.MakeMagma(func(a, b int) int {
return a - b
})
reversedMagma := magma.Reverse(addMagma)
result1 := addMagma.Concat(10, 3) // 10 - 3 = 7
result2 := reversedMagma.Concat(10, 3) // 3 - 10 = -7
FilterFirst - Only applies operation if first argument satisfies predicate:
addMagma := magma.MakeMagma(func(a, b int) int {
return a + b
})
// Only add if first number is positive
filteredMagma := magma.FilterFirst(func(n int) bool {
return n > 0
})(addMagma)
result1 := filteredMagma.Concat(5, 3) // 5 + 3 = 8 (5 is positive)
result2 := filteredMagma.Concat(-5, 3) // 3 (5 is negative, return second)
FilterSecond - Only applies operation if second argument satisfies predicate:
addMagma := magma.MakeMagma(func(a, b int) int {
return a + b
})
// Only add if second number is positive
filteredMagma := magma.FilterSecond(func(n int) bool {
return n > 0
})(addMagma)
result1 := filteredMagma.Concat(5, 3) // 5 + 3 = 8 (3 is positive)
result2 := filteredMagma.Concat(5, -3) // 5 (-3 is negative, return first)
Endo - Applies a function to both arguments before combining:
addMagma := magma.MakeMagma(func(a, b int) int {
return a + b
})
// Double both numbers before adding
doubledMagma := magma.Endo(func(n int) int {
return n * 2
})(addMagma)
result := doubledMagma.Concat(3, 4)
// (3*2) + (4*2) = 6 + 8 = 14
# Array Operations
ConcatAll - Combines all elements in a slice using a magma:
addMagma := magma.MakeMagma(func(a, b int) int {
return a + b
})
numbers := []int{1, 2, 3, 4, 5}
result := magma.ConcatAll(addMagma)(0)(numbers)
// 0 + 1 + 2 + 3 + 4 + 5 = 15
MonadConcatAll - Uncurried version:
addMagma := magma.MakeMagma(func(a, b int) int {
return a + b
})
numbers := []int{1, 2, 3, 4, 5}
result := magma.MonadConcatAll(addMagma)(numbers, 0)
// 0 + 1 + 2 + 3 + 4 + 5 = 15
# Generic Array Operations
The package provides generic versions that work with custom slice types:
type IntSlice []int
addMagma := magma.MakeMagma(func(a, b int) int {
return a + b
})
numbers := IntSlice{1, 2, 3}
result := magma.GenericConcatAll[IntSlice](addMagma)(0)(numbers)
// result is 6
# Practical Examples
Building a max magma:
maxMagma := magma.MakeMagma(func(a, b int) int {
if a > b {
return a
}
return b
})
numbers := []int{3, 7, 2, 9, 1}
maximum := magma.ConcatAll(maxMagma)(0)(numbers)
// maximum is 9
Building a min magma:
minMagma := magma.MakeMagma(func(a, b int) int {
if a < b {
return a
}
return b
})
numbers := []int{3, 7, 2, 9, 1}
minimum := magma.ConcatAll(minMagma)(10)(numbers)
// minimum is 1
Combining strings with separator:
joinMagma := magma.MakeMagma(func(a, b string) string {
if a == "" {
return b
}
if b == "" {
return a
}
return a + ", " + b
})
words := []string{"apple", "banana", "cherry"}
result := magma.ConcatAll(joinMagma)("")(words)
// result is "apple, banana, cherry"
# Relationship to Other Structures
Magma is the base of the algebraic hierarchy:
Magma (no laws)
Semigroup (associative)
Monoid (identity element)
Any Semigroup or Monoid is also a Magma, but not vice versa.
# Functions
Core operations:
- MakeMagma[A any](func(A, A) A) - Create a magma from a binary operation
- First[A any]() - Magma that returns first argument
- Second[A any]() - Magma that returns second argument
Transformations:
- Reverse[A any](Magma[A]) - Swap argument order
- FilterFirst[A any](func(A) bool) - Filter based on first argument
- FilterSecond[A any](func(A) bool) - Filter based on second argument
- Endo[A any](func(A) A) - Apply function before combining
Array operations:
- ConcatAll[A any](Magma[A]) - Combine all elements (curried)
- MonadConcatAll[A any](Magma[A]) - Combine all elements (uncurried)
- GenericConcatAll[GA ~[]A, A any](Magma[A]) - Generic version (curried)
- GenericMonadConcatAll[GA ~[]A, A any](Magma[A]) - Generic version (uncurried)
# Related Packages
- semigroup: Adds associativity law to Magma
- monoid: Adds identity element to Semigroup
*/
package magma