How does a flatMap on a double-generic data-structure looks like?
我有以下(简单)数据结构:
1 2 3 | struct Work<Input, Output> { let work: Input -> Output } |
此类型表示可以占用
函子
1 2 3 4 5 6 7 | extension Work { func map<MoreOutput>(transform: Output -> MoreOutput) -> Work<Input, MoreOutput> { return Work<Input, MoreOutput> { return transform(self.work($0)) } } } |
据我所知,这似乎是正确的。我能够编写一个映射函数,该函数可以将
单子
我很难想到
1 2 3 4 5 6 7 | extension Work { func flatMap<MoreOutput>(transform: Work<Output, MoreOutput>) -> Work<Input, MoreOutput> { return Work<Input, MoreOutput> { input in return transform.work(self.work(input)) } } } |
如果快速查找
1 | func flatMap(transform: (Element) -> T?) -> [T] |
这是一个函数,其参数是将
从另一本功能书籍中,我发现了flatMap的通用定义,如下所示(在对象
1 | func flatMap(f: A -> F) -> F |
有人可以向我解释这种差异吗?甚至有可能在
**编辑
感谢phg提供了许多有用的信息。我试图做Profunctor的定义:
将
1 2 3 4 5 6 7 8 9 | 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) } } } |
您觉得合适吗?
这个:
1 | func flatMap(f: A -> F) -> F |
您要的
1 2 3 4 5 6 7 8 | 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原始文档。 随时以更正的版本进行编辑。
现在到另一个定义:
1 | func flatMap(transform: (Element) -> T?) -> [T] |
我想
1 | func wrappedFlatMap(f: A -> F) -> G |
这可能正是这里的"选项类型"和列表类型正在发生的情况,其中态射在逻辑上只是
1 2 | Just x ~> [x] Nothing ~> [] |