2016-10-22 1 views
1

Voici mes signatures de méthode et définitions scalaQuel est le problème avec la définition de la méthode

def accumulate[T[_]: Traversable, O: Monoid, A]: (A => O) => T[A] => O = 
    fao => ta => 
     (implicitly[Traversable[T]].traverse[({type f[X] = Acc[O, X]})#f, A, O](ta)(a => Acc(fao(a)))).value 

    def reduce[T[_]: Traversable, O: Monoid]: T[O] => O = to => accumulate[T, O, O](a => a)(to) 

Cependant, j'obtiens l'erreur suivante pour ma définition de réduire

Error:(160, 82) not enough arguments for method accumulate: (implicit evidence$7: Traversable[T], implicit evidence$8: Monoid[O])(O => O) => (T[O] => O). 
Unspecified value parameter evidence$8. 
    def reduce[T[_]: Traversable, O: Monoid]: T[O] => O = to => accumulate[T, O, O](a => a)(to) 
                       ^

Je ne sais pas où je vais faux. Toute aide serait appréciée.

Merci!

+1

Il serait plus facile si vous avez fourni une référence aux implémentations de Traversable/Monoid/Acc, afaik scala construit dans traversable n'a pas de méthode de traverse bien que la classe de type Traverse dans scalaz et les chats le font. –

+0

@AngeloGenovese il est sûr de supposer qu'il n'y a qu'une implémentation (légale) de 'Traversable' ou' Monoid' à laquelle il peut se référer ici, c'est la version habituelle que l'on peut trouver dans 'scalaz' ou' cats'. – Yawar

+0

@Yawar juste, mais cela signifie aussi que, afin d'essayer de reproduire son problème, j'ai passé du temps à comprendre ce que Acc ressemblait, et rappelant que les collections de scala Traversable ne sont pas les mêmes que la classe de type Traverse. Assez curieusement, en utilisant des chats et un implicite factice de Acc, je n'ai pas la même erreur de compilation sur Scala 2.10. (gratter cela, juste mon IDE cacher des choses de moi) –

Répondre

2

Vous êtes dérouté par les paramètres cachés (implicites) de la méthode accumulate. Le contexte délimite vous avez placé sur ce que cela signifie que la méthode vraiment a la signature de type:

def accumulate[T[_], O, A](
    implicit traversable: Traversable[T], 
    monoid: Monoid[O]): (A => O) => T[A] => O 

En fait, je vous conseille de pas contexte d'utilisation limites Si vous avez réellement besoin d'utiliser leurs implicits correspondants dans vos méthodes (par opposition à simplement les transmettre implicitement à une autre méthode). Il est beaucoup plus clair de taper les implicites explicitement (ironiquement).

Alors, qu'est-ce qui se passe dans reduce est que vous essayez de passer dans la fonction a => a dans la position où le compilateur attend les deux arguments implicites de Traversable[T] et Monoid[O]. La solution consiste à passer dans les implicits explicitement ou monomorphiseaccumulate avant de l'appeler:

def reduce[T[_]: Traversable, O: Monoid]: T[O] => O = { to => 
    // This forces the compiler to pass in the correct implicits 
    val accumulate_ = accumulate[T, O, O] 
    accumulate_(a => a)(to) 
} 
+0

Merci! Ça marche. Mais pourquoi cela ne fonctionnerait-il pas? accumuler (Traversable [T], Monoïde [O]) (a => a) (à) aussi bien que ce que vous avez écrit. Cela me donne une erreur de compilation. –

+0

@AbdulRahman hmm, peut-être 'Traversable.apply' et' Monoid.apply' ne sont pas définis pour retourner les implicits correctes? Pouvez-vous poster le message d'erreur de compilation? – Yawar

+0

Erreur: (162, 27) objet Traversable ne prend pas les paramètres de type. accumuler (Traversable [T], Monoïde [O]) (a => a) (à) Erreur: (162, 38) objet Monoid ne prend pas les paramètres de type. accumuler (Traversable [T], Monoïde [O]) (a => a) (à) ^ –