2016-04-12 4 views
1
case class KiloGram[A] (value:A) 

val mass= KiloGram(20.0) 

Mit dem scalaz Tag der Verwendung können wir so etwas tun:Was ist der Vorteil scalaz Tag statt einer Fallklasse

import scalaz._ 

sealed trait KiloGram 


def KiloGram[A](a: A): A @@ KiloGram = Tag[A,KiloGram](a) 

val mass = KiloGram(20.0) 

Nun, wenn wir tatsächlich den Wert eines Tagged Objekt verwenden möchten , müssen wir es

val twoTimesMass=2*Tag.unwrap(mass) 

Also wirklich ich auspacken nicht den Nutzen ich über mit einem Fallklasse gewinnen sehen

case class KiloGram[A] (value:A) 

val mass= KiloGram(20.0) 

val twoTimesMass=2*mass.value 

finde ich eigentlich den zweite Ansatz viel weniger ausführlich

+0

Eine bessere Frage value für Fallklassen Aufruf wäre: „Was ist der Vorteil einer scalaz-Tag statt einer Wertklasse der Verwendung (' erstreckt AnyVal ')" –

+0

wollte nicht, um es auf AnyVal zu reduzieren, so habe ich den Beitrag bearbeitet –

+1

Eine Fallklasse hat Overhead, ein Wert (AnyVal) -Klasse nicht, in ähnlicher Weise wie das Tag. Ich persönlich habe die Verwendung von Tagged-Typen wegen Problemen bei der Serialisierung unter Verwendung von json4s gestoppt. –

Antwort

1
  1. Sie können ganz einfach generischen Code schreiben, die für jeden Tagged, wie map[A, B, Tag](x: A @@ Tag)(f: A => B): B @@ Tag arbeitet.

  2. Nach the documentation

    muss man sehr vorsichtig sein, wenn Wertklassen zu verwenden, da es viele Fälle gibt, in denen eine Wert-Klasse wird eine Laufzeit Boxen/Unboxing Ihres Wert entstehen, die verursacht Laufzeitkosten. Die mit Scalaz gekennzeichneten Typen werden niemals zum Boxen eines Wertes führen.

    Obwohl der letzte Satz scheint da Scalaz 7.1 falsch zu sein: https://github.com/scalaz/scalaz/issues/676, https://github.com/scalaz/scalaz/issues/837.

Beachten Sie, dass Sie vermeiden können, in den meisten Fällen mit

object KiloGram { 
    implicit def unwrap[A](x: KiloGram[A]) = x.value 
} 
+0

Können Sie mir ein konkretes Beispiel für Punkt 1 geben, ich verstehe es nicht wirklich ... Was macht das x in Ihrer Kartenfunktion? –

+0

Nun, Sie haben eine Funktion Multiplikation der Masse um 2 für 'KiloGram'. Das Problem ist, wenn Sie dasselbe auch mit 'Gram',' Ton', 'Meter' usw. machen wollen. Bei Fallklassen müssen Sie es duplizieren; Mit 'Tagged' können Sie nur eine generische Funktion schreiben. –

+0

ok, ich sehe, etwa so: def multiplizieren [A <: Doppel, Tag] (tagged: A @@ Tag, mal: Doppel) = { val unwrap = Tag.unwrap (tagged) mal * unwrap } val kgs = multiplizieren (KiloGram (20.0), 2) val m = multiplizieren (Meter (20.0), 2) –

Verwandte Themen