Golang实现类似Elm风格的代码示例

Golang实现类似Elm风格的代码示例 大家好,

TLDR;scion-tools

我想分享一个我一直在开发的包,它直接受到 Elm 的启发,旨在 Go 中实现函数式编程。

在我目前用 Go 进行的工作中,我有些怀念函数式编程带来的便利,因此我着手从 elm/core 移植一些数据结构。

最初是 Dict 包,它是一个不可变且持久的红黑树实现,然后迅速扩展到基本上移植了其他大部分包。

在我钟爱的 Go 惯用模式和我习惯的函数式编程的表达力之间切换,感觉非常棒。

基础示例:

// Dct
Get(1, Singleton(1, "one")) // Just "one"

// List
Foldl(Cons,Empty[int](), [1,2,3]) // [3,2,1]

// Maybe
Map(Sqrt,(Just[Int]{9})) // Just 3

// String
DropLeft(2,"The Lone Gunmen") // "e Lone Gunmen"

你应该能明白。

与 Elm 内核代码类似,内部函数在编写时考虑了尾调用优化,并且是不可变且持久的。

这个包叫做 scion-tools,目前还缺少很多函数,但我一直在添加新的功能。

感谢阅读!


更多关于Golang实现类似Elm风格的代码示例的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang实现类似Elm风格的代码示例的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这是一个非常棒的库!看到Go社区出现受Elm启发的函数式编程工具令人兴奋。scion-tools 在保持Go类型安全的同时,提供了Elm风格的数据结构和操作,这种设计思路很巧妙。

让我用几个具体示例来展示这个库的实用性:

1. Maybe类型的链式操作:

import "github.com/Confidenceman02/scion-tools/maybe"

func getUserEmail(userID int) maybe.Maybe[string] {
    user := maybe.Map(
        func(id int) maybe.Maybe[User] { 
            return findUser(id) 
        },
        maybe.Just(userID),
    )
    
    return maybe.AndThen(
        func(u User) maybe.Maybe[string] { 
            return u.Email 
        },
        user,
    )
}

2. Dict的不可变更新:

import "github.com/Confidenceman02/scion-tools/dict"

// 创建并更新字典
original := dict.Singleton("key1", 100)
updated := dict.Insert("key2", 200, original)

// original保持不变,updated包含新条目
value := dict.Get("key1", updated) // Just 100

3. List的函数式转换:

import "github.com/Confidenceman02/scion-tools/list"

numbers := list.FromSlice([]int{1, 2, 3, 4, 5})

// 过滤和映射的组合
result := list.Foldr(
    func(x int, acc list.List[int]) list.List[int] {
        if x%2 == 0 {
            return list.Cons(x*2, acc)
        }
        return acc
    },
    list.Empty[int](),
    numbers,
) // [8, 4]

4. Result类型的错误处理:

import "github.com/Confidenceman02/scion-tools/result"

func parseAndValidate(input string) result.Result[int, error] {
    return result.AndThen(
        func(n int) result.Result[int, error] {
            if n < 0 {
                return result.Err[int](errors.New("negative number"))
            }
            return result.Ok(n)
        },
        result.Map(strconv.Atoi, result.Ok(input)),
    )
}

这个库特别适合需要不可变数据结构和纯函数式操作的场景。尾调用优化的实现对于处理递归数据结构(如List)的性能很有帮助。期待看到更多Elm核心函数的移植实现!

回到顶部