2.0k sao GitHub và vẫn tăng — IBM/fp-go là dự án Go mà TopGit đang theo dõi trên nền tảng. Functional programming library for Go 1.24+, inspired by fp-ts. Uses generic type aliases for a clean, composable API. Provides Option, Either, Result, IO, IOResult, Reader, and ReaderIOResult monads, plus optics (Lens, Prism, Traversal) for immutable data manipulation. Supports Functor, Applicative, and Monad abstractions with do-notation-style
Tóm tắt dựng từ metadata GitHub của chính dự án — chưa có bài review TopGit. Trang sẽ tự động cập nhật khi bài review đầy đủ được xuất bản.
VÌ SAO CHƯA CÓ REVIEW
TopGit viết bài đầy đủ cho repo có nhiều sao nhất và được yêu cầu nhiều nhất. Trang này là snapshot trong thời gian chờ — xem README gốc ở tab READ ME.
🚧 Work in progress! 🚧 Despite major version 1 (due to semantic-release limitations), we're working to minimize breaking changes.
A comprehensive functional programming library for Go, strongly influenced by the excellent fp-ts library for TypeScript.
📚 Table of Contents
Getting Started
Design Goals
Core Concepts
Comparison to Idiomatic Go
Implementation Notes
Common Operations
Resources
🚀 Getting Started
Installation
go get github.com/IBM/fp-go
Quick Example
import (
"errors"
"github.com/IBM/fp-go/either"
"github.com/IBM/fp-go/function"
)
// Pure function that can fail
func divide(a, b int) either.Either[error, int] {
if b == 0 {
return either.Left[int](errors.New("division by zero"))
}
return either.Right[error](a / b)
}
// Compose operations safely
result := function.Pipe2(
divide(10, 2),
either.Map(func(x int) int { return x * 2 }),
either.GetOrElse(func() int { return 0 }),
)
// result = 10
Resources
📖 API Documentation
💡 Code Samples
🆕 V2 Documentation (requires Go 1.24+)
🎯 Design Goals
This library aims to provide a set of data types and functions that make it easy and fun to write maintainable and testable code in Go. It encourages the following patterns:
Core Principles
Pure Functions: Write many small, testable, and pure functions that produce output only depending on their input and execute no side effects
Side Effect Isolation: Isolate side effects into lazily executed functions using the IO monad
Consistent Composition: Expose a consistent set of composition functions across all data types
Each data type has a small set of composition functions
Functions are named consistently across all data types
Semantics of same-named functions are consistent across data types
🧘🏽 Alignment with the Zen of Go
This library respects and aligns with The Zen of Go:
Principle
Alignment
Explanation
🧘🏽 Each package fulfills a single purpose
✔️
Each top-level package (Option, Either, ReaderIOEither, etc.) defines one data type and its operations
🧘🏽 Handle errors explicitly
✔️
Clear distinction between operations that can/cannot fail; failures represented via Either type
Pure functions are synchronous; I/O operations are asynchronous by default
🧘🏽 Before you launch a goroutine, know when it will stop
🤷🏽
Library doesn't start goroutines; Task monad supports cancellation via context
🧘🏽 Avoid package level state
✔️
No package-level state anywhere
🧘🏽 Simplicity matters
✔️
Small, consistent interface across data types; focus on business logic
🧘🏽 Write tests to lock in behaviour
🟡
Programming pattern encourages testing; library has growing test coverage
🧘🏽 If you think it's slow, first prove it with a benchmark
✔️
Performance claims should be backed by benchmarks
🧘🏽 Moderation is a virtue
✔️
No custom goroutines or expensive synchronization; atomic counters for coordination
🧘🏽 Maintainability counts
✔️
Small, concise operations; pure functions with clear type signatures
💡 Core Concepts
Data Types
The library provides several key functional data types:
Option[A]: Represents an optional value (Some or None)
Either[E, A]: Represents a value that can be one of two types (Left for errors, Right for success)
IO[A]: Represents a lazy computation that produces a value
IOEither[E, A]: Represents a lazy computation that can fail
Reader[R, A]: Represents a computation that depends on an environment
ReaderIOEither[R, E, A]: Combines Reader, IO, and Either for effectful computations with dependencies
Task[A]: Represents an asynchronous computation
State[S, A]: Represents a stateful computation
Monadic Operations
All data types support common monadic operations:
Map: Transform the value inside a context
Chain (FlatMap): Transform and flatten nested contexts
Ap: Apply a function in a context to a value in a context
Of: Wrap a value in a context
Fold: Extract a value from a context
Comparison to Idiomatic Go
This section explains how functional APIs differ from idiomatic Go and how to convert between them.
Pure Functions
Pure functions take input parameters and compute output without changing global state or mutating inputs. They always return the same output for the same input.
Without Errors
If your pure function doesn't return an error, the idiomatic signature works as-is:
func add(a, b int) int {
return a + b
}
With Errors
Idiomatic Go:
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
Functional Style:
func divide(a, b int) either.Either[error, int] {
if b == 0 {
return either.Left[int](errors.New("division by zero"))
}
return either.Right[error](a / b)
}
Conversion:
Use either.EitherizeXXX to convert from idiomatic to functional style
Use either.UneitherizeXXX to convert from functional to idiomatic style
Effectful Functions
An effectful function changes data outside its scope or doesn't always produce the same output for the same input.
Use readerioeither.EitherizeXXX to convert idiomatic Go functions with context to functional style
Implementation Notes
Generics
All monadic operations use Go generics for type safety:
✅ Pros: Type-safe composition, IDE support, compile-time correctness
⚠️ Cons: May result in larger binaries (different versions per type)
💡 Tip: For binary size concerns, use type erasure with any type
Ordering of Generic Type Parameters
Go requires all type parameters on the global function definition. Parameters that cannot be auto-detected come first:
// Map: B cannot be auto-detected, so it comes first
func Map[R, E, A, B any](f func(A) B) func(ReaderIOEither[R, E, A]) ReaderIOEither[R, E, B]
// Ap: B cannot be auto-detected from the argument
func Ap[B, R, E, A any](fa ReaderIOEither[R, E, A]) func(ReaderIOEither[R, E, func(A) B]) ReaderIOEither[R, E, B]
This ordering maximizes type inference where possible.
Use of the ~ Operator
Go doesn't support generic type aliases (until Go 1.24), only type definitions. The ~ operator allows generic implementations to work with compatible types:
type ReaderIOEither[R, E, A any] RD.Reader[R, IOE.IOEither[E, A]]
Generic Subpackages:
Each higher-level type has a generic subpackage with fully generic implementations
These are for library extensions, not end-users
Main packages specialize generic implementations for convenience
Higher Kinded Types (HKT)
Go doesn't support HKT natively. This library addresses this by:
Introducing HKTs as individual types (e.g., HKTA for HKT[A])
Implementing generic algorithms in the internal package
Keeping complexity hidden from end-users
Common Operations
Map/Chain/Ap/Flap
Operator
Parameter
Monad
Result
Use Case
Map
func(A) B
HKT[A]
HKT[B]
Transform value in context
Chain
func(A) HKT[B]
HKT[A]
HKT[B]
Transform and flatten
Ap
HKT[A]
HKT[func(A)B]
HKT[B]
Apply function in context
Flap
A
HKT[func(A)B]
HKT[B]
Apply value to function in context
Example: Chaining Operations
import (
"github.com/IBM/fp-go/either"
"github.com/IBM/fp-go/function"
)
result := function.Pipe3(
either.Right[error](10),
either.Map(func(x int) int { return x * 2 }),
either.Chain(func(x int) either.Either[error, int] {
if x > 15 {
return either.Right[error](x)
}
return either.Left[int](errors.New("too small"))
}),
either.GetOrElse(func() int { return 0 }),
)
📚 Resources
API Documentation
Code Samples
V2 Documentation - New features in Go 1.24+
fp-ts - Original TypeScript inspiration
🤝 Contributing
Contributions are welcome! Please feel free to submit issues or pull requests.
📄 License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
IBM/fp-go thuộc nhóm Backend trên TopGit, cùng 6 topic GitHub. Trang Trending và Topics liệt kê các repo cùng số sao và cùng ngôn ngữ để so sánh.
Đọc thêm về IBM/fp-go ở đâu?
Trang TopGit này là một snapshot — tab "Readme" hiển thị nguyên văn README của repo (đã bỏ link, giữ ảnh). Repo GitHub ở github.com/IBM/fp-go là nguồn chính thức.
IBM/fp-go có bao nhiêu sao?
IBM/fp-go có 2.0k sao GitHub — tải lại trang để xem số mới nhất, hoặc xem trực tiếp github.com/IBM/fp-go. TopGit phản chiếu số sao của GitHub nhưng không cam kết đến từng phút.
IBM/fp-go có phải mã nguồn mở không?
Có — IBM/fp-go phát hành theo license Apache-2.0, nghĩa là mã nguồn mở để đọc, fork và (tùy license) tái sử dụng. Mã: github.com/IBM/fp-go.
IBM/fp-go có trang demo không?
Dự án có trang chủ ở https://github.com/IBM/fp-go/tree/main/v2. Tab "Readme" ở trang này thường có ảnh chụp và hướng dẫn bắt đầu nhanh.
IBM/fp-go là gì?
IBM/fp-go (IBM/fp-go) là dự án Go trên GitHub. Theo mô tả gốc: Functional programming library for Go 1.24+, inspired by fp-ts. Uses generic type aliases for a clean, composable API. Provides Option, Either, Result, IO, IOResult, Reader, and ReaderIOResult monads, plus optics (Lens, Prism, Traversal) for immutable data manipulation. Supports Functor, Applicative, and Monad abstractions with do-notation-style
IBM/fp-go so với các dự án Backend khác thế nào?
IBM/fp-go được TopGit xếp vào nhóm Backend, với 2.0k sao GitHub và viết bằng Go. Xem trang chủ đề Backend trên TopGit để so sánh với các dự án tương tự theo số sao và mức độ hoạt động.
Đọc đầy đủ README ở tab phía trên.
Muốn nghe thêm một ý kiến về fp-go?
Hỏi một AI đọc được trang này — một cú bấm là có ngay nhận định về fp-go.