2016-09-29 2 views
2

Ich mache eine einfache Übung aus dem Buch Advanced scala with cats auf eigene Faust.Scala mit Katzen - Cartesian + Validiert

Ich möchte Cartesian mit Validated verwenden.

/* 
this works 
*/ 
type ValidatedString = Validated[ Vector[String], String] 
Cartesian[ValidatedString].product(
    "a".valid[Vector[String]], 
    "b".valid[Vector[String]] 
) 

/* this doesnt work*/ 
type Result[A] = Validated[List[String], A] 
Cartesian[ValidatedString].product(
    f(somevariable)//returns Result[String], 
    g(somevariable)//returns Result[Int], 
).map(User.tupled) // creates an user from the returned string, int 

Im völlig ahnungslos. Irgendwelche Hinweise? Im erhalten:

could not find implicit value for parameter instance: cats.Cartesian[Result] Cartesian[Result].product( ^

+0

In Ihrem ersten Beispiel definieren Sie 'ValidatedString' in Bezug auf' Vector [] ', während Sie es im zweiten Beispiel als' List [] 'definieren. Ist das ein echter Unterschied? –

+0

Es ist ein kleiner Punkt, aber Ihr erstes Code-Snippet funktioniert _doesn_ nicht, da 'ValidatedString' kein Typkonstruktor ist. Es würde diese Frage für zukünftige Leser nützlicher machen, um sicherzustellen, dass Ihr Code korrekt beschrieben wird. –

Antwort

4

Ohne Ihre Importe zu sehen, würde ich die Frage erraten ist, dass Sie eine Semigroup Instanz für List sind vermisst (oder Vector-es ist nicht klar, was Sie verwenden möchten), da die folgende Arbeiten für mich:

import cats.instances.list._ 
import cats.syntax.validated._ 
:

import cats.Cartesian, cats.data.Validated, cats.implicits._ 

type Result[A] = Validated[List[String], A] 

Cartesian[Result].product(
    "a".valid[List[String]], 
    "a".valid[List[String]] 
) 

Sie könnten den cats.implicits._ Teil mit dem folgenden ersetzen

... aber ich würde vorschlagen, mit cats.implicits._ zu beginnen.

Das Problem hierbei ist, dass Validated Ausfälle ansammelt, wenn Sie zwei Instanzen mit product kombinieren, und was „sammeln“ bedeutet, in einem bestimmten Kontext durch eine Semigroup-Instanz für den ungültigen Typen bestimmt wird, die Sie sagt, wie man zwei ungültig „add“ Werte zusammen.

Im Falle von List (oder Vector), macht Verkettung Sinn für diese Akkumulationsoperation und Katzen bietet die Verkettung Semigroup für jede List[A], aber um es zu bekommen hier angewendet werden Sie es explizit importieren müssen (entweder von cats.implicits oder von cats.instances.list).

+0

Ich vermisste 'import cats.implicits._' danke! –