gpt4 book ai didi

swift - 双泛型数据结构上的 flatMap 是什么样子的?

转载 作者:行者123 更新时间:2023-11-30 10:08:19 25 4
gpt4 key购买 nike

我有以下(简单)数据结构:

struct Work<Input, Output> {
let work: Input -> Output
}

此类型代表可能需要 Input 的工作并变成所需的 Output 。我想看看这个数据结构是否符合一些函数概念,如仿函数或单子(monad)。

仿函数

extension Work {
func map<MoreOutput>(transform: Output -> MoreOutput) -> Work<Input, MoreOutput> {
return Work<Input, MoreOutput> {
return transform(self.work($0))
}
}
}

据我所知,这似乎是正确的。我能够编写一个 map 函数,它可以将 Work<Input, Output>进入Work<Input, MoreOutput>

单子(monad)

我很难想到 flatMap 的定义(或 fold )函数 Work 。我唯一能想到的是:

extension Work {
func flatMap<MoreOutput>(transform: Work<Output, MoreOutput>) -> Work<Input, MoreOutput> {
return Work<Input, MoreOutput> { input in
return transform.work(self.work(input))
}
}
}

如果您查找flatMap Array 的定义很快它看起来像这样(简化):

func flatMap(transform: (Element) -> T?) -> [T]

这是一个函数,其参数是一个转换 Element 的函数。进入T结果是 Array 。我想不出一种方法可以将其抽象为 Work类型。

从另一本功能书中,我找到了 flatMap 的一般定义,如下(在对象 F 持有类型 A 上):

func flatMap<B>(f: A -> F<B>) -> F<B>

这是 flatMap 的不同定义比Array似乎实现了。

有人可以向我解释一下这种差异吗?是否有可能定义一个“正确”flatMap功能于 Work ?或者Work不满足成为 Monad 的属性?

** 编辑

感谢 phg 提供这么多有用的信息。我尝试过定义 Profunctor:

制作Work一个Profunctor :

extension Work {
func diMap<A, B>(fa: A -> Input, fb: Output -> B) -> Work<A, B> {
return Work<A, B> { arg in
let input = fa(arg)
let output = self.work(input)
return fb(output)
}
}
}

您觉得这样合适吗?

最佳答案

这个:

func flatMap<B>(f: A -> F<B>) -> F<B>

就是你想要的flatMap看起来像;这是 monad 的惯用 "bind" operation 。专门针对第二个参数的函数,您会得到所谓的 Reader monad :

extension Work {
func flatMap<MoreOutput>(g: Output -> Work<Input, MoreOutput>) -> Work<Input, MoreOutput> {
// (Reader f) >>= g = Reader $ \x -> runReader (g (f x)) x
return Work<Input, MoreOutput> {
g(self.work($0)).work($0)
}
}
}

注意:我实际上不会说 Swift,这段代码只是猜测——因此包含了 Haskell 原始代码。请随意在更正的版本中进行编辑。

<小时/>

现在来看另一个定义:

func flatMap(transform: (Element) -> T?) -> [T]

我想T?意思是“可选 T ”或“可为空 T ”。这不是我们通常理解的一元函数,但它是相关的。确实,已经有a question关于这种“广义平面 map ”。答案是,如果两个单子(monad)兼容,即存在单子(monad)态射F<A> -> G<A>保留一元结构,定义是有意义的

func wrappedFlatMap<B>(f: A -> F<B>) -> G<B>

这可能正是“选项类型”和列表类型所发生的情况,其中态射在逻辑上只是

Just x ~> [x]
Nothing ~> []

关于swift - 双泛型数据结构上的 flatMap 是什么样子的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34802632/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com