2015-10-27 2 views
0

У меня есть код, возвращающий Future[String \/ Response], экземпляры монады для обоих Disjunction и Future и функции getResult: Response => [String \/ Result]. Теперь это написано с несколькими вложенными функциями, и я хочу увидеть его следующим образомMonad трансформатор для дизъюнкции и будущего

for { 
    response <- getResponse 
    result <- getResult(response) 
} yield result // Future[String \/ Result] 

Как я могу понять, монада трансформаторы используют именно для этой цели, и я мог бы сделать similar вещи, если бы я Option вместо \/. Но, к сожалению, я не смог найти FutureT или DisjunctionT (хотя для кошек существует XorT).

Итак, можно ли написать монодальный трансформатор для цели? Может быть, он уже существует или я что-то не понимаю.

ответ

2

Вы можете использовать scalaz.EitherT, чтобы комбинировать эффекты \/ (Дизъюнкция) и еще одну монашку, в вашем случае Future.

def getResponse: Future[String \/ Response] = ??? 
def getResult(resp: Reponse): Future[String \/ Result] = ??? 

(for { 
    response <- EitherT(getResponse) 
    result <- EitherT(getResult(response)) 
} yield result).run 
// Future[String \/ Result] 

Или вы можете изменить типы возврата функций getResponse и getResult вернуться EitherT:

type R[A] = EitherT[Future, String, A] 

def getResponse: R[Response] = ??? 
def getResult(resp: Reponse): R[Result] = ??? 

(for { 
    response <- getResponse 
    result <- getResult(response) 
} yield result).run 
// Future[String \/ Result] 
+0

Эй Питер. Спасибо, что указал мне на скалаз, но я пропустил его. К сожалению, оба примера не работали: сначала один, потому что 'getResult' не возвращает Future, второй потому, что обе функции не соответствуют типу R [_]. В любом случае, это работает: 'EitherT (getResponse) .map (getResult) .run' и немного лучше, чем моя предыдущая реализация. Также мне все еще интересно, что делать, когда у вас нет трансформатора. – chuwy

+0

UPD: нет, я ошибаюсь. Моя карта приводит к вложенной дизъюнкции. Я, вероятно, мог бы «присоединиться», но это выглядит совсем не изящно. – chuwy

+0

'map' действительно является функцией от' EitherT [F, A, B] 'до' EitherT [F, A, C] ', поэтому вы получаете' EitherT [F, String, String \/Result] '. Решением может быть использование 'flatMapF':' EitherT (getInt) .flatMapF (getRes (_). Point [Future]). Run'. –

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

  • Нет связанных вопросов^_^