2017-12-08 4 views
3

Ich kann kein Functor für meine abstract class Foo[V : Monoid], die eine Typ-Einschränkung haben. Dies ist wegen der map Methode von Functor, die eine B Parameter, die keine Monoid ist.Wie Typ Einschränkung zu Funktoren zuordnen Funktion

Meine Frage ist, wie und wo kann ich solche Einschränkung hinzufügen?

Hier ist eine Probe von dem, was ich versuche zu tun:

import cats.Functor 
import cats.kernel.Monoid 

abstract class Foo[A : Monoid] { 
    val a: A 
} 

object Foo { 
    implicit def FooFunctor = new Functor[Foo] { 
    override def map[A, B](fa: Foo[A])(f: (A) => B) = new Foo[B] { 
     override val a: B = f(fa.a) 
    } 
    } 
} 

erhöhen diese die folgende Ausnahme:

Error:(12, 59) could not find implicit value for evidence parameter of type cats.kernel.Monoid[B] 
    override def map[A, B](fa: Foo[A])(f: (A) => B) = new Foo[B] { 

Meine erste Lösung in der map Definition der Einschränkung wurde hinzugefügt (override def map[A, B : Monoid]) Dies ist jedoch nicht zulässig, da dies die Definition der Funktion in Functor ändern und die Ausnahme auslösen wird:

Error:(12, 18) method map overrides nothing. 

Kann mir bitte jemand helfen, rauszukommen? jeder Vorschlag würde geschätzt werden.

+0

Ist das nicht ein Fall, wenn Sie ein 'Applicative' anstelle eines' Functor' brauchen? Auf diese Weise könntest du 'Foo [B]' mit 'reinem [Foo [B]]' erstellen. –

+0

Dies sieht wie ein typisches [XY-Problem] aus (https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Können Sie Ihr tatsächliches Problem beschreiben, das Sie mit diesem Code lösen möchten? Ihr '' Foo' ', wie es jetzt ist, ist kein 'Functor' nach der Definition von' cats', weil' cats.Functor' über jeden möglichen Typ definiert werden muss. Aber vielleicht ist das nicht das, was du wirklich brauchst. Geben Sie also Ihr High-Level-Problem an und jemand könnte eine bessere Lösung finden. – SergGr

Antwort

0

Ich denke, das Hauptproblem ist, dass Sie versuchen, Sub-Typisierung mit Typ-Klassen zu mischen. Sollte sein:

trait Foo[A] extends Monoid[A] with Functor[A] { 
    val a: A 
} 

trait SomeADT 
case class SomeValue(a: String) extends SomeADT 

object SomeADT { 
    //evidence 
} 
+0

Das bleibt immer noch unvollständig. –