Pure package detail
fp
gno.land/p/moul/fp/v2
Indexed deployment identity with independently loaded latest RPC source. Functions and Render are realm-only RPC capabilities.
Indexed deployment
Identity
- Package path
- gno.land/p/moul/fp/v2
- Block
- 23340
- Deployed (UTC)
- Transaction
- Apy6VajdUg2EnZUsfDZ0+zPldktKl3XZyZiGlJ7u13c=
Latest RPC state
Source
// Package fp provides functional programming utilities for Gno, enabling
// transformations, filtering, and other operations on slices of any.
//
// Example of chaining operations:
//
// numbers := []any{1, 2, 3, 4, 5, 6}
//
// // Define predicates, mappers and reducers
// isEven := func(v any) bool { return v.(int)%2 == 0 }
// double := func(v any) any { return v.(int) * 2 }
// sum := func(a, b any) any { return a.(int) + b.(int) }
//
// // Chain operations: filter even numbers, double them, then sum
// evenNums := Filter(numbers, isEven) // [2, 4, 6]
// doubled := Map(evenNums, double) // [4, 8, 12]
// result := Reduce(doubled, sum, 0) // 24
//
// // Alternative: group by even/odd, then get even numbers
// byMod2 := func(v any) any { return v.(int) % 2 }
// grouped := GroupBy(numbers, byMod2) // {0: [2,4,6], 1: [1,3,5]}
// evens := grouped[0] // [2,4,6]
package fp
// Mapper is a function type that maps an element to another element.
type Mapper func(any) any
// Predicate is a function type that evaluates a condition on an element.
type Predicate func(any) bool
// Reducer is a function type that reduces two elements to a single value.
type Reducer func(any, any) any
// Filter filters elements from the slice that satisfy the given predicate.
//
// Example:
//
// numbers := []any{-1, 0, 1, 2}
// isPositive := func(v any) bool { return v.(int) > 0 }
// result := Filter(numbers, isPositive) // [1, 2]
func Filter(values []any, fn Predicate) []any {
result := []any{}
for _, v := range values {
if fn(v) {
result = append(result, v)
}
}
return result
}
// Map applies a function to each element in the slice.
//
// Example:
//
// numbers := []any{1, 2, 3}
// toString := func(v any) any { return fmt.Sprintf("%d", v) }
// result := Map(numbers, toString) // ["1", "2", "3"]
func Map(values []any, fn Mapper) []any {
result := make([]any, len(values))
for i, v := range values {
result[i] = fn(v)
}
return result
}
// Reduce reduces a slice to a single value by applying a function.
//
// Example:
//
// numbers := []any{1, 2, 3, 4}
// sum := func(a, b any) any { return a.(int) + b.(int) }
// result := Reduce(numbers, sum, 0) // 10
func Reduce(values []any, fn Reducer, initial any) any {
acc := initial
for _, v := range values {
acc = fn(acc, v)
}
return acc
}
// FlatMap maps each element to a collection and flattens the results.
//
// Example:
//
// words := []any{"hello", "world"}
// split := func(v any) any {
// chars := []any{}
// for _, c := range v.(string) {
// chars = append(chars, string(c))
// }
// return chars
// }
// result := FlatMap(words, split) // ["h","e","l","l","o","w","o","r","l","d"]
func FlatMap(values []any, fn Mapper) []any {
result := []any{}
for _, v := range values {
inner := fn(v).([]any)
result = append(result, inner...)
}
return result
}
// All returns true if all elements satisfy the predicate.
//
// Example:
//
// numbers := []any{2, 4, 6, 8}
// isEven := func(v any) bool { return v.(int)%2 == 0 }
// result := All(numbers, isEven) // true
func All(values []any, fn Predicate) bool {
for _, v := range values {
if !fn(v) {
return false
}
}
return true
}
// Any returns true if at least one element satisfies the predicate.
//
// Example:
//
// numbers := []any{1, 3, 4, 7}
// isEven := func(v any) bool { return v.(int)%2 == 0 }
// result := Any(numbers, isEven) // true (4 is even)
func Any(values []any, fn Predicate) bool {
for _, v := range values {
if fn(v) {
return true
}
}
return false
}
// None returns true if no elements satisfy the predicate.
//
// Example:
//
// numbers := []any{1, 3, 5, 7}
// isEven := func(v any) bool { return v.(int)%2 == 0 }
// result := None(numbers, isEven) // true (no even numbers)
func None(values []any, fn Predicate) bool {
for _, v := range values {
if fn(v) {
return false
}
}
return true
}
// Chunk splits a slice into chunks of the given size.
//
// Example:
//
// numbers := []any{1, 2, 3, 4, 5}
// result := Chunk(numbers, 2) // [[1,2], [3,4], [5]]
func Chunk(values []any, size int) [][]any {
if size <= 0 {
return nil
}
var chunks [][]any
for i := 0; i < len(values); i += size {
end := i + size
if end > len(values) {
end = len(values)
}
chunks = append(chunks, values[i:end])
}
return chunks
}
// Find returns the first element that satisfies the predicate and a boolean indicating if an element was found.
//
// Example:
//
// numbers := []any{1, 2, 3, 4}
// isEven := func(v any) bool { return v.(int)%2 == 0 }
// result, found := Find(numbers, isEven) // 2, true
func Find(values []any, fn Predicate) (any, bool) {
for _, v := range values {
if fn(v) {
return v, true
}
}
return nil, false
}
// Reverse reverses the order of elements in a slice.
//
// Example:
//
// numbers := []any{1, 2, 3}
// result := Reverse(numbers) // [3, 2, 1]
func Reverse(values []any) []any {
result := make([]any, len(values))
for i, v := range values {
result[len(values)-1-i] = v
}
return result
}
// Zip combines two slices into a slice of pairs. If the slices have different lengths,
// extra elements from the longer slice are ignored.
//
// Example:
//
// a := []any{1, 2, 3}
// b := []any{"a", "b", "c"}
// result := Zip(a, b) // [[1,"a"], [2,"b"], [3,"c"]]
func Zip(a, b []any) [][2]any {
length := min(len(a), len(b))
result := make([][2]any, length)
for i := 0; i < length; i++ {
result[i] = [2]any{a[i], b[i]}
}
return result
}
// Unzip splits a slice of pairs into two separate slices.
//
// Example:
//
// pairs := [][2]any{{1,"a"}, {2,"b"}, {3,"c"}}
// numbers, letters := Unzip(pairs) // [1,2,3], ["a","b","c"]
func Unzip(pairs [][2]any) ([]any, []any) {
a := make([]any, len(pairs))
b := make([]any, len(pairs))
for i, pair := range pairs {
a[i] = pair[0]
b[i] = pair[1]
}
return a, b
}
// GroupBy groups elements based on a key returned by a Mapper.
//
// Example:
//
// numbers := []any{1, 2, 3, 4, 5, 6}
// byMod3 := func(v any) any { return v.(int) % 3 }
// result := GroupBy(numbers, byMod3) // {0: [3,6], 1: [1,4], 2: [2,5]}
func GroupBy(values []any, fn Mapper) map[any][]any {
result := make(map[any][]any)
for _, v := range values {
key := fn(v)
result[key] = append(result[key], v)
}
return result
}
// Flatten flattens a slice of slices into a single slice.
//
// Example:
//
// nested := [][]any{{1,2}, {3,4}, {5}}
// result := Flatten(nested) // [1,2,3,4,5]
func Flatten(values [][]any) []any {
result := []any{}
for _, v := range values {
result = append(result, v...)
}
return result
}
// Helper functions
func min(a, b int) int {
if a < b {
return a
}
return b
}
The verified vm/qfuncs operation accepts realm paths only.
Pure packages expose source files but do not have Realm Render.