Skip to main content
Version: v2.2.82 (latest)
Reference · Collections

Record Applicative

Applying maps of functions to maps of values. Applicative operations enable function application across map structures.

01

Core API

FunctionSignatureDescription
Apfunc Ap[K comparable, A, B any](Monoid[K, B]) func(map[K]func(A) B) func(map[K]A) map[K]BApply functions to values
Flapfunc Flap[K comparable, A, B any](A) func(map[K]func(A) B) map[K]BApply value to functions
02

Usage Examples

Ap - Apply Functions

ap.go
import (
  R "github.com/IBM/fp-go/v2/record"
  M "github.com/IBM/fp-go/v2/monoid"
  F "github.com/IBM/fp-go/v2/function"
)

fns := map[string]func(int) int{
  "double": func(n int) int { return n * 2 },
  "square": func(n int) int { return n * n },
}

values := map[string]int{
  "a": 5,
  "b": 3,
}

// Apply all functions to all values
result := F.Pipe2(
  values,
  R.Ap(M.MergeMonoid[string, int]())(fns),
)
// Result depends on merge strategy
// Combines function and value maps

Flap - Apply Value

flap.go
fns := map[string]func(int) string{
  "double": func(n int) string {
      return fmt.Sprintf("Double: %d", n*2)
  },
  "square": func(n int) string {
      return fmt.Sprintf("Square: %d", n*n)
  },
  "triple": func(n int) string {
      return fmt.Sprintf("Triple: %d", n*3)
  },
}

// Apply single value to all functions
result := F.Pipe2(
  fns,
  R.Flap(5),
)
// map[string]string{
//   "double": "Double: 10",
//   "square": "Square: 25",
//   "triple": "Triple: 15",
// }

Multiple Transformations

multiple.go
type Validator func(string) bool

validators := map[string]Validator{
  "length":    func(s string) bool { return len(s) >= 5 },
  "uppercase": func(s string) bool { return s == strings.ToUpper(s) },
  "numeric":   func(s string) bool { return regexp.MustCompile(`^[0-9]+$`).MatchString(s) },
}

// Test a value against all validators
results := F.Pipe2(
  validators,
  R.Flap("HELLO"),
)
// map[string]bool{
//   "length": true,
//   "uppercase": true,
//   "numeric": false,
// }

Formatting Pipeline

format.go
type Formatter func(float64) string

formatters := map[string]Formatter{
  "currency": func(n float64) string {
      return fmt.Sprintf("$%.2f", n)
  },
  "percent": func(n float64) string {
      return fmt.Sprintf("%.1f%%", n*100)
  },
  "scientific": func(n float64) string {
      return fmt.Sprintf("%.2e", n)
  },
}

value := 0.12345

formatted := F.Pipe2(
  formatters,
  R.Flap(value),
)
// map[string]string{
//   "currency": "$0.12",
//   "percent": "12.3%",
//   "scientific": "1.23e-01",
// }
03

Common Patterns

Validation Suite

validation.go
type ValidationRule func(User) error

rules := map[string]ValidationRule{
  "email": func(u User) error {
      if !strings.Contains(u.Email, "@") {
          return errors.New("invalid email")
      }
      return nil
  },
  "age": func(u User) error {
      if u.Age < 18 {
          return errors.New("must be 18+")
      }
      return nil
  },
}

user := User{Email: "test@example.com", Age: 25}

// Run all validations
results := F.Pipe2(
  rules,
  R.Flap(user),
)
// map[string]error{
//   "email": nil,
//   "age": nil,
// }

Data Transformers

transformers.go
transformers := map[string]func(string) string{
  "lowercase": strings.ToLower,
  "uppercase": strings.ToUpper,
  "title":     strings.Title,
}

input := "hello world"

transformed := F.Pipe2(
  transformers,
  R.Flap(input),
)
// map[string]string{
//   "lowercase": "hello world",
//   "uppercase": "HELLO WORLD",
//   "title": "Hello World",
// }

Applicative Pattern: Flap is particularly useful when you have a collection of functions and want to apply a single value to all of them, producing a map of results.