Вопрос по scala, playframework-2.0, scalaz – Асинхронное вычисление с проверкой в Scala с использованием Scalaz

7

Поскольку я пишу полностью асинхронную библиотеку для доступа к удаленному сервису (используя 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

Я уже давно собираюсь использовать ScalaZ с моими приложениями Play, и это очень удачно для меня. Я сообщу вам, как у меня дела, и, надеюсь, я смогу дать содержательный ответ здесь. opyate
Да уж! Спасибо. На самом деле настоящая проблема не в использовании ScalaZ с Play. Это более общий вопрос (о f & # xB0; prog), потому что без Play (то есть только ScalaZ) я использовалIO вместоPromise, Следовательно, у меня будет та же самая схема, что и сказать:IO[Validation[E, A]] andy petrella

Ваш Ответ

1   ответ
4

монадные трансформаторы, Вкратце, монадные трансформаторы компенсируютмонады не сочиняющие позволяя вам «сложить» их.

Вы не упомянули версию Scalaz, которую вы используете, но если вы посмотрите наскалаз-семь филиал, вы найдетеValidationT, Это может быть использовано, чтобы обернуть любойF[Validation[E, A]] вValidationT[F, E, A]где в вашем случаеF = Promise, Если вы изменитеf а такжеg возвращатьValidationTтогда вы можете оставить свой код как

for {
  x ← f(a)
  y ← g(b)
} yield y

Это даст вамValidationT[Promise, E, B] в следствии.

Мммм, смотри, что я ищу !! Итак, сначала я попробую с монадным трансформатором себя, по двум причинам, потому что это единственный способ учиться, и во-вторых, потому что я на ветке 6.0.4. И тогда я, вероятно, перейду к 7-му и проведу рефакторинг для ValidatorT ... Во всех случаях я вернусь сюда, чтобы рассказать больше. еще раз спасибо andy petrella
Хорошо. Отличный док. Я посмотрел вValidationT егоflatMap метод действительно то, что мне нужно (и, как я думаю, он такой же, как мой/~~> один). Но для того, чтобы использовать его напрямую,Promise нужен экземпляр TypeClassMonad, что это "десятки". Поэтому, когда выйдет ScalaZ, я реализую его, чтобы иметь возможность использоватьValidationT непосредственно. andy petrella

Похожие вопросы