2015-04-28 3 views
2

Например, существуют два класса: A и B. И есть метод в A под названием toB.В Scala, как сделать преобразование типов для Future [Option [A]]?

Теперь есть значение a, которое имеет тип Future[Option[A]], какой будет самый элегантный способ его преобразования в Future[Option[B]]?

В настоящее время я использую a.map(_.map(_.toB)), но я думаю, что это выглядит немного неуклюжим и запутанным. У кого-нибудь есть лучшие способы сделать это? (неявное преобразование) Спасибо!

+0

@CarlosVilchez не работает. –

+0

Являются ли 'A' и' B' совершенно несвязанными классами? – muhuk

+0

карта/карта выглядит хорошо для меня. –

ответ

4

Если вам нужно работать много на «стек» из Future[Option[?]] вы можете использовать monad transformer:

val a: OptionT[Future, A] = OptionT(...) 
val b: OptionT[Future, B] = a.map(_.toB) 
2

Если вы готовы бросить некоторые scalaz там, вы могли бы написать обобщенную функцию для это:

import scalaz._ 
import Scalaz._ 

def mapF[F[_]: Functor, G[_]:Functor,A,B](fg: F[G[A]], h : A => B) : F[G[B]] = fg.map(_.map(h)) 

он использует «уродливый» mapmap версию, но она будет работать для любого Functor. Если вы хотите использовать его инфикс, просто создать неявный класс для него:

implicit class toMapF[F[_]:Functor,G[_]:Functor, A](fg : F[G[A]]){ 
    def mapF[B](f: A => B) = fg.map(_.map(f)) 
    } 

Затем вы можете использовать его как:

a.mapF(_.toB) 

Это, конечно, абсолютной излишним, если вы уже используете scalaz, но любая причина хороша, чтобы попробовать.

+0

Я думаю, что это уже существует в scalaz как ['compose'] (https://github.com/scalaz/scalaz/blob/series/7.2.x/core/src/main/scala/scalaz/Functor.scala#L62)? – Lee

+0

Честно говоря, трудно найти абстракцию, которая уже не находится в 'scalaz'. Я пытаюсь с помощью 'Functor [List]' .compose.map (a) (_. ToB) ', но получаю некоторую проблему с неявным расширением. Это выглядит многообещающим, хотя я попытаюсь заставить его работать, спасибо, что указали это. – Chirlo

Смежные вопросы