2017-02-10 1 views
3

문자열에서 전처리 단계를 수행하고 있습니다. 내 단계의 안전성을 높이기 위해 HList을 사용하려고합니다. 일부 처리 단계는 다른 처리 단계 이후에 실행되어야하므로 유형 시스템에서이를 인코딩 할 생각이었습니다. 내 첫 번째 시도했다 : 그것이 작동하는 가능한 순서입니다 순서 doA>doB>doDependsOnA>doDependsOnB, 모든 것을 전화하라고 강제하기 때문에유형이 HList의 멤버 인 경우 엉성한 체크 인은 어떻게합니까?

trait Step 
trait Raw extends Step 
trait A extends Step 
trait B extends Step 
trait DependsOnA extends Step 
trait DependsOnB extends Step 

case class ToBeProcessed[S <: Step](value: String) 

object ToBeProcessed { 
    def raw(input: String): ToBeProcessed[Raw] = ... 
    def doA(input: ToBeProcessed[Raw]): ToBeProcessed[A] = ... 
    def doB(input: ToBeProcessed[A]): ToBeProcessed[B] = ... 
    def doDependsOnA(input: ToBeProcessed[B]): ToBeProcessed[DependsOnA] = ... 
    def doDependsOnB(input: ToBeProcessed[DependsOnA]): ToBeProcessed[DependsOnB] = ... 
} 

이, 작동하지만 :

  1. 서로 의존하지 않는 단계간에 종속성을 강요합니다.
  2. 새로운 중간 단계를 구현하려면 doC 관련이없는 유형을 변경해야합니다.

그래서 저는 하스켈에서 타입 레벨리스트를 읽기 시작했고 그것을 사용하여 내 의존성을 인코딩 할 수 있음을 깨달았습니다. 그래서 나는 볼품 HList의에 읽기 시작하고이 튀어 :

def doDependsOnA[S <: HList, ???](input: ToBeProcessed[S]): ToBeProcessed[DependsOnA :: S] = ... 

} 

곳에서 :

case class ToBeProcessed[S <: HList](value: String) 

object ToBeProcessed { 
    def raw(input: String): ToBeProcessed[Raw :: HNil] = ... 
    def doA[S <: HList](input: ToBeProcessed[S]): ToBeProcessed[A :: S] = ... 
    def doB[S <: HList](input: ToBeProcessed[S]): ToBeProcessed[B :: S] = ... 

내가하는을 확인 할 수있는 방법이 있어야합니다 종속성을 인코딩 주어진 HList에 포함 ??? 타입은 반드시 에 A을 포함하도록 인코딩해야합니다. 나는 아직도 어떻게해야할지 모르겠다. 이것이 가능한가?

답변

2

셰이프리스는 이미 HListSelector이 포함되어 있음을 증명하는 typeclass가 있습니다. 다음과 같이 사용하십시오 :

import shapeless._, ops.hlist.Selector 

def doDependsOnA[S <: HList](input: ToBeProcessed[S])(implicit ev: Selector[S,A]): ToBeProcessed[DependsOnA :: S] = ??? 
+0

Beautiful! 무리 감사. 나는 오늘 더 일찍이 그것을 찾지 못한 형태의 코드를 들여다 보았지만 이것에 대해 비틀 거리지 않았다. –

관련 문제