1
0
mirror of https://github.com/IBM/fp-go.git synced 2025-11-25 22:21:49 +02:00
Files
fp-go/v2/pair/monad.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

316 lines
10 KiB
Go

// Copyright (c) 2024 - 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 pair
import (
"github.com/IBM/fp-go/v2/internal/applicative"
"github.com/IBM/fp-go/v2/internal/functor"
"github.com/IBM/fp-go/v2/internal/monad"
"github.com/IBM/fp-go/v2/internal/pointed"
"github.com/IBM/fp-go/v2/monoid"
"github.com/IBM/fp-go/v2/semigroup"
)
type (
pairPointedHead[A, B any] struct {
m monoid.Monoid[B]
}
pairFunctorHead[A, B, A1 any] struct {
}
pairApplicativeHead[A, B, A1 any] struct {
s semigroup.Semigroup[B]
m monoid.Monoid[B]
}
pairMonadHead[A, B, A1 any] struct {
s semigroup.Semigroup[B]
m monoid.Monoid[B]
}
pairPointedTail[A, B any] struct {
m monoid.Monoid[A]
}
pairFunctorTail[A, B, B1 any] struct {
}
pairApplicativeTail[A, B, B1 any] struct {
s semigroup.Semigroup[A]
m monoid.Monoid[A]
}
pairMonadTail[A, B, B1 any] struct {
s semigroup.Semigroup[A]
m monoid.Monoid[A]
}
)
func (o *pairMonadHead[A, B, A1]) Of(a A) Pair[A, B] {
return MakePair(a, o.m.Empty())
}
func (o *pairMonadHead[A, B, A1]) Map(f func(A) A1) func(Pair[A, B]) Pair[A1, B] {
return MapHead[B](f)
}
func (o *pairMonadHead[A, B, A1]) Chain(f func(A) Pair[A1, B]) func(Pair[A, B]) Pair[A1, B] {
return ChainHead(o.s, f)
}
func (o *pairMonadHead[A, B, A1]) Ap(fa Pair[A, B]) func(Pair[func(A) A1, B]) Pair[A1, B] {
return ApHead[B, A, A1](o.s, fa)
}
func (o *pairPointedHead[A, B]) Of(a A) Pair[A, B] {
return MakePair(a, o.m.Empty())
}
func (o *pairFunctorHead[A, B, A1]) Map(f func(A) A1) func(Pair[A, B]) Pair[A1, B] {
return MapHead[B](f)
}
func (o *pairApplicativeHead[A, B, A1]) Map(f func(A) A1) func(Pair[A, B]) Pair[A1, B] {
return MapHead[B](f)
}
func (o *pairApplicativeHead[A, B, A1]) Ap(fa Pair[A, B]) func(Pair[func(A) A1, B]) Pair[A1, B] {
return ApHead[B, A, A1](o.s, fa)
}
func (o *pairApplicativeHead[A, B, A1]) Of(a A) Pair[A, B] {
return MakePair(a, o.m.Empty())
}
// MonadHead implements the monadic operations for [Pair] operating on the head value.
// Requires a monoid for the tail type to provide an identity element for the Of operation
// and a semigroup for combining tail values in Chain and Ap operations.
//
// Example:
//
// import M "github.com/IBM/fp-go/v2/monoid"
//
// stringMonoid := M.MakeMonoid(
// func(a, b string) string { return a + b },
// "",
// )
// monad := pair.MonadHead[int, string, int](stringMonoid)
// p := monad.Of(42) // Pair[int, string]{42, ""}
func MonadHead[A, B, A1 any](m monoid.Monoid[B]) monad.Monad[A, A1, Pair[A, B], Pair[A1, B], Pair[func(A) A1, B]] {
return &pairMonadHead[A, B, A1]{s: monoid.ToSemigroup(m), m: m}
}
// PointedHead implements the pointed operations for [Pair] operating on the head value.
// Requires a monoid for the tail type to provide an identity element.
//
// Example:
//
// import M "github.com/IBM/fp-go/v2/monoid"
//
// stringMonoid := M.MakeMonoid(
// func(a, b string) string { return a + b },
// "",
// )
// pointed := pair.PointedHead[int, string](stringMonoid)
// p := pointed.Of(42) // Pair[int, string]{42, ""}
func PointedHead[A, B any](m monoid.Monoid[B]) pointed.Pointed[A, Pair[A, B]] {
return &pairPointedHead[A, B]{m: m}
}
// FunctorHead implements the functor operations for [Pair] operating on the head value.
//
// Example:
//
// functor := pair.FunctorHead[int, string, string]()
// mapper := functor.Map(func(n int) string { return fmt.Sprintf("%d", n) })
// p := pair.MakePair(42, "hello")
// p2 := mapper(p) // Pair[string, string]{"42", "hello"}
func FunctorHead[A, B, A1 any]() functor.Functor[A, A1, Pair[A, B], Pair[A1, B]] {
return &pairFunctorHead[A, B, A1]{}
}
// ApplicativeHead implements the applicative operations for [Pair] operating on the head value.
// Requires a monoid for the tail type to provide an identity element for the Of operation
// and a semigroup for combining tail values in the Ap operation.
//
// Example:
//
// import M "github.com/IBM/fp-go/v2/monoid"
//
// stringMonoid := M.MakeMonoid(
// func(a, b string) string { return a + b },
// "",
// )
// applicative := pair.ApplicativeHead[int, string, string](stringMonoid)
// pf := applicative.Of(func(n int) string { return fmt.Sprintf("%d", n) })
// pv := pair.MakePair(42, "!")
// result := applicative.Ap(pv)(pf) // Pair[string, string]{"42", "!"}
func ApplicativeHead[A, B, A1 any](m monoid.Monoid[B]) applicative.Applicative[A, A1, Pair[A, B], Pair[A1, B], Pair[func(A) A1, B]] {
return &pairApplicativeHead[A, B, A1]{s: monoid.ToSemigroup(m), m: m}
}
func (o *pairMonadTail[A, B, B1]) Of(b B) Pair[A, B] {
return MakePair(o.m.Empty(), b)
}
func (o *pairMonadTail[A, B, B1]) Map(f func(B) B1) func(Pair[A, B]) Pair[A, B1] {
return MapTail[A](f)
}
func (o *pairMonadTail[A, B, B1]) Chain(f func(B) Pair[A, B1]) func(Pair[A, B]) Pair[A, B1] {
return ChainTail(o.s, f)
}
func (o *pairMonadTail[A, B, B1]) Ap(fa Pair[A, B]) func(Pair[A, func(B) B1]) Pair[A, B1] {
return ApTail[A, B, B1](o.s, fa)
}
func (o *pairPointedTail[A, B]) Of(b B) Pair[A, B] {
return MakePair(o.m.Empty(), b)
}
func (o *pairFunctorTail[A, B, B1]) Map(f func(B) B1) func(Pair[A, B]) Pair[A, B1] {
return MapTail[A](f)
}
func (o *pairApplicativeTail[A, B, B1]) Map(f func(B) B1) func(Pair[A, B]) Pair[A, B1] {
return MapTail[A](f)
}
func (o *pairApplicativeTail[A, B, B1]) Ap(fa Pair[A, B]) func(Pair[A, func(B) B1]) Pair[A, B1] {
return ApTail[A, B, B1](o.s, fa)
}
func (o *pairApplicativeTail[A, B, B1]) Of(b B) Pair[A, B] {
return MakePair(o.m.Empty(), b)
}
// MonadTail implements the monadic operations for [Pair] operating on the tail value.
// Requires a monoid for the head type to provide an identity element for the Of operation
// and a semigroup for combining head values in Chain and Ap operations.
//
// Example:
//
// import M "github.com/IBM/fp-go/v2/monoid"
//
// intSum := M.MonoidSum[int]()
// monad := pair.MonadTail[string, int, int](intSum)
// p := monad.Of("hello") // Pair[int, string]{0, "hello"}
func MonadTail[B, A, B1 any](m monoid.Monoid[A]) monad.Monad[B, B1, Pair[A, B], Pair[A, B1], Pair[A, func(B) B1]] {
return &pairMonadTail[A, B, B1]{s: monoid.ToSemigroup(m), m: m}
}
// PointedTail implements the pointed operations for [Pair] operating on the tail value.
// Requires a monoid for the head type to provide an identity element.
//
// Example:
//
// import M "github.com/IBM/fp-go/v2/monoid"
//
// intSum := M.MonoidSum[int]()
// pointed := pair.PointedTail[string, int](intSum)
// p := pointed.Of("hello") // Pair[int, string]{0, "hello"}
func PointedTail[B, A any](m monoid.Monoid[A]) pointed.Pointed[B, Pair[A, B]] {
return &pairPointedTail[A, B]{m: m}
}
// FunctorTail implements the functor operations for [Pair] operating on the tail value.
//
// Example:
//
// functor := pair.FunctorTail[string, int, int]()
// mapper := functor.Map(func(s string) int { return len(s) })
// p := pair.MakePair(5, "hello")
// p2 := mapper(p) // Pair[int, int]{5, 5}
func FunctorTail[B, A, B1 any]() functor.Functor[B, B1, Pair[A, B], Pair[A, B1]] {
return &pairFunctorTail[A, B, B1]{}
}
// ApplicativeTail implements the applicative operations for [Pair] operating on the tail value.
// Requires a monoid for the head type to provide an identity element for the Of operation
// and a semigroup for combining head values in the Ap operation.
//
// Example:
//
// import M "github.com/IBM/fp-go/v2/monoid"
//
// intSum := M.MonoidSum[int]()
// applicative := pair.ApplicativeTail[string, int, int](intSum)
// pf := applicative.Of(func(s string) int { return len(s) })
// pv := pair.MakePair(5, "hello")
// result := applicative.Ap(pv)(pf) // Pair[int, int]{5, 5}
func ApplicativeTail[B, A, B1 any](m monoid.Monoid[A]) applicative.Applicative[B, B1, Pair[A, B], Pair[A, B1], Pair[A, func(B) B1]] {
return &pairApplicativeTail[A, B, B1]{s: monoid.ToSemigroup(m), m: m}
}
// Monad implements the monadic operations for [Pair] operating on the tail value (alias for MonadTail).
// This is the default monad instance for Pair.
//
// Example:
//
// import M "github.com/IBM/fp-go/v2/monoid"
//
// intSum := M.MonoidSum[int]()
// monad := pair.Monad[string, int, int](intSum)
// p := monad.Of("hello") // Pair[int, string]{0, "hello"}
func Monad[B, A, B1 any](m monoid.Monoid[A]) monad.Monad[B, B1, Pair[A, B], Pair[A, B1], Pair[A, func(B) B1]] {
return MonadTail[B, A, B1](m)
}
// Pointed implements the pointed operations for [Pair] operating on the tail value (alias for PointedTail).
// This is the default pointed instance for Pair.
//
// Example:
//
// import M "github.com/IBM/fp-go/v2/monoid"
//
// intSum := M.MonoidSum[int]()
// pointed := pair.Pointed[string, int](intSum)
// p := pointed.Of("hello") // Pair[int, string]{0, "hello"}
func Pointed[B, A any](m monoid.Monoid[A]) pointed.Pointed[B, Pair[A, B]] {
return PointedTail[B](m)
}
// Functor implements the functor operations for [Pair] operating on the tail value (alias for FunctorTail).
// This is the default functor instance for Pair.
//
// Example:
//
// functor := pair.Functor[string, int, int]()
// mapper := functor.Map(func(s string) int { return len(s) })
// p := pair.MakePair(5, "hello")
// p2 := mapper(p) // Pair[int, int]{5, 5}
func Functor[B, A, B1 any]() functor.Functor[B, B1, Pair[A, B], Pair[A, B1]] {
return FunctorTail[B, A, B1]()
}
// Applicative implements the applicative operations for [Pair] operating on the tail value (alias for ApplicativeTail).
// This is the default applicative instance for Pair.
//
// Example:
//
// import M "github.com/IBM/fp-go/v2/monoid"
//
// intSum := M.MonoidSum[int]()
// applicative := pair.Applicative[string, int, int](intSum)
// pf := applicative.Of(func(s string) int { return len(s) })
// pv := pair.MakePair(5, "hello")
// result := applicative.Ap(pv)(pf) // Pair[int, int]{5, 5}
func Applicative[B, A, B1 any](m monoid.Monoid[A]) applicative.Applicative[B, B1, Pair[A, B], Pair[A, B1], Pair[A, func(B) B1]] {
return ApplicativeTail[B, A, B1](m)
}