mirror of
https://github.com/IBM/fp-go.git
synced 2025-11-23 22:14:53 +02:00
156 lines
5.4 KiB
Go
156 lines
5.4 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 reader
|
|
|
|
import (
|
|
G "github.com/IBM/fp-go/v2/reader/generic"
|
|
)
|
|
|
|
// These functions curry a Go function with the context as the first parameter into a Reader
|
|
// with the context as the last parameter, which is equivalent to a function returning a Reader
|
|
// of that context.
|
|
//
|
|
// This follows the Go convention (https://pkg.go.dev/context) of putting the context as the
|
|
// first parameter, while Reader monad convention has the context as the last parameter.
|
|
|
|
// Curry0 converts a function that takes a context and returns a value into a Reader.
|
|
//
|
|
// Example:
|
|
//
|
|
// type Config struct { Value int }
|
|
// getValue := func(c Config) int { return c.Value }
|
|
// r := reader.Curry0(getValue)
|
|
// result := r(Config{Value: 42}) // 42
|
|
func Curry0[R, A any](f func(R) A) Reader[R, A] {
|
|
return G.Curry0[Reader[R, A]](f)
|
|
}
|
|
|
|
// Curry1 converts a function with context as first parameter into a curried function
|
|
// returning a Reader. The context parameter is moved to the end (Reader position).
|
|
//
|
|
// Example:
|
|
//
|
|
// type Config struct { Prefix string }
|
|
// addPrefix := func(c Config, s string) string { return c.Prefix + s }
|
|
// curried := reader.Curry1(addPrefix)
|
|
// r := curried("hello")
|
|
// result := r(Config{Prefix: ">> "}) // ">> hello"
|
|
func Curry1[R, T1, A any](f func(R, T1) A) Kleisli[R, T1, A] {
|
|
return G.Curry1[Reader[R, A]](f)
|
|
}
|
|
|
|
// Curry2 converts a function with context as first parameter and 2 other parameters
|
|
// into a curried function returning a Reader.
|
|
//
|
|
// Example:
|
|
//
|
|
// type Config struct { Sep string }
|
|
// join := func(c Config, a, b string) string { return a + c.Sep + b }
|
|
// curried := reader.Curry2(join)
|
|
// r := curried("hello")("world")
|
|
// result := r(Config{Sep: "-"}) // "hello-world"
|
|
func Curry2[R, T1, T2, A any](f func(R, T1, T2) A) func(T1) func(T2) Reader[R, A] {
|
|
return G.Curry2[Reader[R, A]](f)
|
|
}
|
|
|
|
// Curry3 converts a function with context as first parameter and 3 other parameters
|
|
// into a curried function returning a Reader.
|
|
//
|
|
// Example:
|
|
//
|
|
// type Config struct { Format string }
|
|
// format := func(c Config, a, b, d string) string {
|
|
// return fmt.Sprintf(c.Format, a, b, d)
|
|
// }
|
|
// curried := reader.Curry3(format)
|
|
// r := curried("a")("b")("c")
|
|
// result := r(Config{Format: "%s-%s-%s"}) // "a-b-c"
|
|
func Curry3[R, T1, T2, T3, A any](f func(R, T1, T2, T3) A) func(T1) func(T2) func(T3) Reader[R, A] {
|
|
return G.Curry3[Reader[R, A]](f)
|
|
}
|
|
|
|
// Curry4 converts a function with context as first parameter and 4 other parameters
|
|
// into a curried function returning a Reader.
|
|
//
|
|
// Example:
|
|
//
|
|
// type Config struct { Multiplier int }
|
|
// sum := func(c Config, a, b, d, e int) int {
|
|
// return (a + b + d + e) * c.Multiplier
|
|
// }
|
|
// curried := reader.Curry4(sum)
|
|
// r := curried(1)(2)(3)(4)
|
|
// result := r(Config{Multiplier: 10}) // 100
|
|
func Curry4[R, T1, T2, T3, T4, A any](f func(R, T1, T2, T3, T4) A) func(T1) func(T2) func(T3) func(T4) Reader[R, A] {
|
|
return G.Curry4[Reader[R, A]](f)
|
|
}
|
|
|
|
// Uncurry0 converts a Reader back into a regular function with context as first parameter.
|
|
//
|
|
// Example:
|
|
//
|
|
// type Config struct { Value int }
|
|
// r := reader.Of[Config](42)
|
|
// f := reader.Uncurry0(r)
|
|
// result := f(Config{Value: 0}) // 42
|
|
func Uncurry0[R, A any](f Reader[R, A]) func(R) A {
|
|
return G.Uncurry0(f)
|
|
}
|
|
|
|
// Uncurry1 converts a curried function returning a Reader back into a regular function
|
|
// with context as first parameter.
|
|
//
|
|
// Example:
|
|
//
|
|
// type Config struct { Prefix string }
|
|
// curried := func(s string) reader.Reader[Config, string] {
|
|
// return reader.Asks(func(c Config) string { return c.Prefix + s })
|
|
// }
|
|
// f := reader.Uncurry1(curried)
|
|
// result := f(Config{Prefix: ">> "}, "hello") // ">> hello"
|
|
func Uncurry1[R, T1, A any](f Kleisli[R, T1, A]) func(R, T1) A {
|
|
return G.Uncurry1(f)
|
|
}
|
|
|
|
// Uncurry2 converts a curried function with 2 parameters returning a Reader back into
|
|
// a regular function with context as first parameter.
|
|
//
|
|
// Example:
|
|
//
|
|
// type Config struct { Sep string }
|
|
// curried := func(a string) func(string) reader.Reader[Config, string] {
|
|
// return func(b string) reader.Reader[Config, string] {
|
|
// return reader.Asks(func(c Config) string { return a + c.Sep + b })
|
|
// }
|
|
// }
|
|
// f := reader.Uncurry2(curried)
|
|
// result := f(Config{Sep: "-"}, "hello", "world") // "hello-world"
|
|
func Uncurry2[R, T1, T2, A any](f func(T1) func(T2) Reader[R, A]) func(R, T1, T2) A {
|
|
return G.Uncurry2(f)
|
|
}
|
|
|
|
// Uncurry3 converts a curried function with 3 parameters returning a Reader back into
|
|
// a regular function with context as first parameter.
|
|
func Uncurry3[R, T1, T2, T3, A any](f func(T1) func(T2) func(T3) Reader[R, A]) func(R, T1, T2, T3) A {
|
|
return G.Uncurry3(f)
|
|
}
|
|
|
|
// Uncurry4 converts a curried function with 4 parameters returning a Reader back into
|
|
// a regular function with context as first parameter.
|
|
func Uncurry4[R, T1, T2, T3, T4, A any](f func(T1) func(T2) func(T3) func(T4) Reader[R, A]) func(R, T1, T2, T3, T4) A {
|
|
return G.Uncurry4(f)
|
|
}
|