说我有2个函子f0和f1,我有一些看起来像这样的代码-
1
| f0.map(v0 => f1.map(v1 => f0f1(v0, v1))) |
有没有一种方法可以简化此过程,以便可以使用for表达式并使代码更简洁-
1 2 3 4
| for {
v0 <- f0
v1 <- f1
} yield f0f1 (v0, v1 ) |
map功能可通过如下形式的语法糖使用:-
1 2 3 4
| implicit class FunctorOps [F [_], A ](fa : F [A ]) {
def F = implicitly [Functor [F ]]
def map [B ](ab : A => B ): F [B ] = F. map(fa )(ab )
} |
- 就我而言,它实际上类似于— IO[Option[X]]
-
我不想真正关心我的值的容器是什么,我想对内部的内容进行转换
-
@LuisMiguelMejíaSuárez你们在说什么? Future突然来自哪里?哪个Functor实现具有一个带有单个参数的map?它们都有两个参数,该函数通常排在第二位。不清楚您要问什么,请提供一个最小的可复制示例。
-
@AndreyTyukin我正在使用Cats,因为map被添加为语法糖。
-
@Tushar然后尚不清楚要添加什么语法糖。 f0和f1到底是什么。看起来,它们不是Functor[F]的实例。
-
@AndreyTyukin我添加了Cats自动插入的语法糖
-
Cats的摘要应如何阐明代码中f0和f1的类型?我们知道Cats中的代码是什么样的。我们不知道您的代码中的f0和f1是什么。
-
让我们继续聊天中的讨论。
假设f0: F0[X]和f1: F1[Y](其中F0和F1都具有Functor实例)和f: (X, Y) => Z,则for理解等效于
1
| f0.map(x => f1.map(y => f(x, y))) |
将是
示例:
产生:
1
| res1: Option[List[Int]] = Some(List(42, 84, 126)) |
而
产生
1
| res2: List[Option[Int]] = List(Some(42), Some(84), Some(126)) |
在这种情况下,我不确定for的理解是否比嵌套的map更清晰。
我认为原则上您不可能追求的目标。
您追求的漂亮的for语法会转换为类似
1
| f0.flatMap(v0 => (f1.map(v1 => f0f1(v0, v1)))) |
这里的问题是flatMap部分。要有一个flatMap,您需要一个
Monad,不仅是Functor,或者至少是flatMap
实例。但是与Functor相比,Monad不组成。所以没有
从F[_]和G[_]自动获取嵌套的Monad的方法,即使两者
它们是Monad。 [1]
使用某些monad转换器可能会获得不错的语法,但是它们
所有单子都不存在(也不能存在)。 [2]
对于有变压器的单子,可能会出现您想要的东西:
1 2 3 4 5 6 7
| val l : List [Int ] = List (1, 2, 3)
val o : Option [String ] = Some ("abc")
val ol : OptionT [List, String ] = for {
a <- OptionT. liftF(l )
b <- OptionT. fromOption[List ](o )
} yield a + b. toString |
如果您对OptionT感兴趣,可以使用scala文档([3])。
这是更好还是不好看在情人眼中。
可悲的是,如果您更经常需要此功能,则可能需要按照
的方式编写自己的帮助程序功能
1 2 3 4 5 6
| def combine2 [F [_]: Functor, G [_]: Functor, A, B, C ](
fa : F [A ],
gb : G [B ])(
f : (A, B ) => C
): F [G [C ]] =
fa. map(a => gb. map(b => (f (a, b )))) |
如果您不想这样做,您可以做的一件事就是已经提到的@ andrey-tyukin。但我同意,最好只嵌套对map的调用。
您可能要看的另一件事是Nested [4]。在这种特殊情况下,它无济于事,但可以帮助您减少一些嵌套的map。
-
[1] http://blog.tmorris.net/posts/monads-do-not-compose/
[2]为什么Haskell中没有IO转换器?
[3] https://typelevel.org/cats/api/cats/data/OptionT.html
[4] https://typelevel.org/cats/api/cats/data/Nested.html