2016-07-26 2 views
1

List로 접을 때 Hlist에서 foldLeft가 작동하지 않습니다. Hlist를 문자열로 접을 때 모든 것이 올바르게 작동합니다. hList의 다음 요소 (42,와 호환되지 않습니다 foldedHList2Shapeless : foldLeft on hlist 컴파일 오류

could not find implicit value for parameter folder: 
shapeless.ops.hlist.LeftFolder[shapeless.::[String,shapeless.::[Int,shapeless.HNil]],scala.collection.immutable.Nil.type,com.test.Test.foldListPoly.type] 
+1

오류를 추가 할 수 있습니까? –

+0

질문이 컴파일 오류로 업데이트되었습니다. – andresrcom

답변

2

있습니다 그 변종은 HListHList에서 List[Any]을 효율적으로 계산하고 HList을보다 정확하게 입력 한으로 변환하는 toList 메서드를 효율적으로 계산하는 runtimeList 메서드를 정의합니다.. 그럼에도 불구하고 fold을 사용하여이 작업을 수행하는 방법을 확인하는 것은 흥미 롭습니다.

여기에는 몇 가지 주름이 있습니다. 고려해야 할 첫 번째 사항은 여기에 누적 된 List의 유형이어야합니다. 대부분의 경우 결과 목록의 요소 유형이 접히는 HList 요소 유형의 최소 상한값 (LUB)이되도록 할 수 있습니다. 이러한 유형의 결과를 얻으려면 우리가가는 것처럼 LUB를 계산해야합니다.

또한 초기 값으로 Nil을 수용해야합니다. NilList[Nothing] 유형의 값이며 암시 적 색인을 List[T]으로 해결해야하는 경우 문제가됩니다. 변수 TNil의 유형과 일치하도록 Nothing에 인스턴스화해야하지만 불행히도 유형의 변수 값으로 Nothing을 유형 변수로 처리합니다. 결과는 "암시 적"입니다. 거짓으로 실패합니다. 이 문제를 해결하려면 Nil.type에 대해 foldListPoly의 명시적인 사례를 제공해야합니다. 이러는

함께 우리는 각 경우에 결과리스트의 요소 유형은 HList의 소자 종류의 LUB 것을

object wrapInList extends Poly1 { 
    implicit def default[T] = at[T]{v => List(v)} 
} 

object foldListPoly extends Poly2 { 
    implicit def foldToListNil[U](implicit st: wrapInList.Case.Aux[U, List[U]]) = 
    at[Nil.type, U]{ (acc, u) => wrapInList(u) } 

    implicit def foldToList[T, U, L, LL](
    implicit st: wrapInList.Case.Aux[U, List[U]], 
    lub: Lub[T, U, L], 
    llub: Lub[List[T], List[U], LL], 
    ev: LL =:= List[L] 
) = at[List[T], U]{ (acc, u) => llub.left(acc) ::: llub.right(wrapInList(u)) } 
} 

scala> ("aoeu" :: 42 :: HNil).foldLeft(Nil)(foldListPoly) 
res0: List[Any] = List(aoeu, 42) 

scala> (13 :: 23 :: HNil).foldLeft(Nil)(foldListPoly) 
res1: List[Int] = List(13, 23) 

scala> (23 :: true :: HNil).foldLeft(Nil)(foldListPoly) 
res2: List[AnyVal] = List(23, true) 

통지를 끝낸다.

0

문제를 컴파일하는 것은 당신이 wrapInList에서 "aoeu"에 대한 List[String]을 생성한다는 것입니다에

object wrapInList extends Poly1 { 
    implicit def intCase = at[Int]{v => List(v)} 
    implicit def stringCase = at[String]{v => List(v)} 
} 

object mergeToString extends Poly1 { 
    implicit def intCase = at[Int](_.toString()) 
    implicit def stringCase = at[String](identity) 
} 

object foldListPoly extends Poly2 { 
    implicit def foldToList[T](implicit st: wrapInList.Case.Aux[T, List[T]]) = 
    at[List[T], T]{ (acc, t) => acc ::: wrapInList(t) } 
    implicit def foldToString[T](implicit st: mergeToString.Case.Aux[T, String]) = 
    at[String, T]{ (acc, t) => acc + mergeToString(t)} 
} 

val hList = "aoeu" :: 42 :: HNil 
val foldedHlist = hList.foldLeft("")(foldListPoly) 
val foldedHList2 = hList.foldLeft(Nil)(foldListPoly) 

Erorr하는 Int). 당신이 (바운드 가장 상위에 반대) List[Any] 살 수 있다면, 당신은 이런 식으로 작업을 수행 할 수 있습니다

object wrapInList extends Poly1 { 
    implicit def intCase = at[Int]{v => List[Any](v)} 
    implicit def stringCase = at[String]{v => List[Any](v)} 
} 

object foldListPoly extends Poly2 { 
    implicit def foldToList[T](implicit st: wrapInList.Case.Aux[T, List[Any]]) = 
    at[List[Any], T]{ (acc, t) => acc ::: wrapInList(t) } 
} 

를 또한 명시 적으로 NilList[Any]으로 입력해야 :

val foldedHList2 = hList.foldLeft(Nil:List[Any])(foldListPoly) 
+0

나는 호환되지 않는 타입에 대한 아이디어를 얻었지만, 불행하게도이 코드는 컴파일되지 않고'hList'를 폴드하려고 할 때 같은 에러를줍니다. – andresrcom

+0

죄송합니다,'List [Any]'유형을 포함하는 메소드 호출을 포함하는 것을 잊었습니다. – devkat