Асинхронное вычисление с проверкой в Scala с использованием Scalaz

Поскольку я пишу полностью асинхронную библиотеку для доступа к удаленному сервису (используя Play2.0), я используюPromise а такжеValidation создать неблокирующий вызов, который имеет тип, представляющий сбой и правильный результат сразу.

Promise происходит от Play2-Scala, гдеValidation исходит от скалаза.

Так вот тип примеров таких функций

f :: A => Promise[Validation[E, B]] g :: B => Promise[Validation[E, C]]

Пока все хорошо, теперь, если я хочу их составить, я могу просто использовать тот факт, чтоPromise представитьflatMapтак что я могу сделать это для понимания

for (
   x <- f(a);
   y <- g(b)
) yield y

Хорошо, я взял ярлык к моей проблеме здесь, потому что я не использовал повторноValidation результаты в пределах для понимания. Так что, если я хочу использовать повторноx вgвот как я мог сделать

for (
   x <- f(a); // x is a Validation
   y <- x.fold(
      fail => Promise.pure(x),
      ok => g(ok)
   )
) yield y

Достаточно справедливо, но этот тип шаблона будет загрязнять мой код снова и снова. Проблема здесь заключается в том, что я представляю собой своего рода двухуровневую монадическую структуру, такую какM[N[_]].

На данном этапе, есть ли какая-либо структура в f & # xB0; программирование, которое позволяет работать с такой структурой, легко пропуская уровень secong:

for (
   x <- f(a); //x is a B
   y <- g(b) 
) yield y

Теперь ниже показано, как я добился чего-то подобного.

Я создал вид монадической структуры, которая объединяет два уровня в один, скажем,ValidationPromised который сутенерPromise введите два метода:

def /~> [EE >: E, B](f: Validation[E, A] => ValidationPromised[EE, B]): ValidationPromised[EE, B] = 
    promised flatMap { valid => 
        f(valid).promised
    }

def /~~>[EE >: E, B](f: A => ValidationPromised[EE, B]): ValidationPromised[EE, B] = 
    promised flatMap { valid => 
        valid.fold (
            bad => Promise.pure(KO(bad)),
            good => f(good).promised
        )
    }

Это позволяет мне делать такие вещи

      endPoint.service /~~>                                   //get the service
      (svc =>                                                 //the service
        svc.start /~~> (st =>                                 //get the starting elt
          svc.create(None) /~~>                               //svc creates a new elt
          (newE =>                                            //the created one
            newEntry.link(st, newE) /~~>                      //link start and the new
            (lnk => Promise.pure(OK((st, lnk, newE))))        //returns a triple => hackish 
          ) 
        )
      )

Как мы можем видеть/~~> очень похоже наflatMap но пропускает один уровень. Проблема заключается в многословии (именно поэтому «для понимания» существует в Scala и «делаю» в Haskell).

Еще один момент, который я/~> что стоит какmap также, но работает на втором уровне (вместо типа Valid -third уровень)

Итак, мой второй вопрос является следствием первого ... Я подхожу к устойчивому решению с этой конструкцией?

sorry to be that long

Ответы на вопрос(1)

Ваш ответ на вопрос