2012-06-14 15 views
7

Próbuję użyć bezkształtnego, aby gromadzić łatwo obiekty w bezpieczny sposób.Bezkształtne: Przygotuj. Niejawne nie znaleziono

Problem polega na tym, że chcę dołączyć (:::) dwa HList. Znam problem początkujący (wydaje się przynajmniej). Tęskni za niejawną instancją Prepend w kontekście.

Jednak patrząc na hlist.scala, widzę, że ogólny implicit def są zdefiniowane w obiektach Prepend i PrependAux.

Dodanie import Prepend i import PrependAux ręcznie nic nie zmieniło (oczywiście ...).

Więc tutaj kod zredukowana do minimum:

enter code here 

import shapeless._ 
import HList._ 
import Prepend._ 
import PrependAux._ 

object test { 

    val a:HList = 1 :: 4 :: "A" :: HNil 
    val b:HList = "R" :: false :: HNil 

    val c:HList = a ::: b // <<<<<<<<<<< NEEDS A Prepend in the context 

} 

W konsoli teraz:

[error]  test.scala:10: could not find implicit value for parameter prepend: shapeless.Prepend[shapeless.HList,shapeless.HList] 
[error]  val c:HList = a ::: b // this needs an implicit Prepend in the current context 

Co należy spalić oczy?

dzięki

EDIT

Mała aktualizacja do ponownego complexify nieco prawdziwy problem, bo do wulgaryzacja było przed silnym.

Oto coś takiego, że będę w stanie to zrobić:

case class A[L<:HList](a:L) { 
    def doSmth[C <:HList](c:C) = a ::: c 
} 

Więc nie mam dostępu do rzeczywistego typu, tylko wiem, że są one HList s.

+0

jedyne odpowiedzi zostały również zaktualizowane. i nadal działa. Rzeczą, której brakowało w moim rozwiązaniu, była najwyraźniej opcja skalak ... –

Odpowiedz

10

Problem polega na tym, że powstanie do HList jest problemem. Nie możesz prawie nic zrobić ze zwykłym starym HList (oprócz dodawania do niego nowych elementów).

Można też zapewnić bardziej pouczające typu adnotacji:

val a: Int :: Int :: String :: HNil = 1 :: 4 :: "A" :: HNil 
val b: String :: Boolean :: HNil = "R" :: false :: HNil 
val c: Int :: Int :: String :: String :: Boolean :: HNil = a ::: b 

Albo po prostu niech rodzaje wywnioskować, który jest zwykle znacznie bardziej wygodne:

val a = 1 :: 4 :: "A" :: HNil 
val b = "R" :: false :: HNil 
val c = a ::: b 

W odpowiedzi na Twój komentarz : możesz zrobić to, co chcesz, jeśli upewnisz się, że masz dowody, których potrzebujesz (zauważ, że założyłem, że a: A było literówką dla a: L, a tha t trzeba -Ydependent-method-types to zadziałało):

case class A[L <: HList](a: L) { 
    def doSmth[C <: HList](c: C)(implicit p: Prepend[L, C]) = a ::: c 
} 

Ogólnie można po prostu spojrzeć na implicits, które są niezbędne do prowadzenia działalności, której używasz, a następnie dołączyć je na swojej metody.

+0

Thx, masz całkowitą rację (więc walidowałem oczywiście). W rzeczywistości mój przykład zmniejszył zbyt duży problem.Ponieważ mój problem tkwi w rodzajach rzeczy (nieco mniej zredukowanych): 'case class A [L <: HList] (a: A) {def doSmth [C <: HList] (c: C) = a ::: c} '. Co myślisz? –

+0

@ andypetrella: Edytowałem, aby odpowiedzieć na twoje pytanie. –

+0

Masz rację za literówkę! Przepraszam za to. Po aktualizacji (również zaktualizuję pytanie). Właściwie to zrobiłem i prawdopodobnie potrzebowałem opcji, o której mówiłeś, żeby to działało. Jeszcze raz, niedługo to wypróbuję. –