this question에 따르면 스프레이는 ApplyConverter
인스턴스를 생성하기 위해 sbt-boilerplate를 사용하여 암시 적으로 A :: B :: ... :: HNil => R
을보다 일반적인 용도로 (A, B, ...) => R
으로 변환합니다. 그 질문은 1 년 전에 물었다. 예를 들어 매크로 나 Shapeless의 새로운 기능을 사용하여 외부 코드 생성 단계가 필요하지 않도록 할 수 있습니까?HLists를 인수 목록으로 변환하는 상용구가없는 방법이 있습니까?
답변
매우 오랫동안 엉성한 부분에 포함되었습니다. 형태가없는 2.0.0에서는 다음을 할 수 있습니다.
scala> import shapeless._, syntax.std.function._
import shapeless._
import syntax.std.function._
scala> val f1: (Int, String, Boolean) => Int = (i, s, b) => i+s.length+(if(b) 1 else 0)
f1: (Int, String, Boolean) => Int = <function3>
scala> val pf1 = f1.toProduct
pf1: Int :: String :: Boolean :: HNil => Int = <function1>
scala> pf1(23 :: "foo" :: true :: HNil)
res0: Int = 27
scala> val pf2: (Int :: String :: HNil) => Int = l => l.head+l.tail.head.length
pf2: Int :: String :: HNil => Int = <function1>
scala> val f2 = pf2.fromProduct
f2: (Int, String) => Int = <function2>
scala> f2(23, "foo")
res1: Int = 26
(가독성을 위해 REPL 결과 유형 렌더링을 정리).
순수 스칼라에서는 이것을 수행 할 방법이 없다고 생각합니다. FunctionN
인터페이스에 대해 일반적으로 이야기 할 방법이 없기 때문입니다. 거시적 인 수준에서는 가능한 것이지만 AST 표현을 사용할 수있는 방식이 아닙니다. 이 작업을 수행하는 매크로는 아마도 문자열 조작을 (효과적으로) 줄일 수 있습니다.이 경우 sbt-boilerplate에 비해 거의 이점이 없습니다.
스프레드는 다른 라이브러리와 함께 사용할 수 있어야하는 상당히 기초적인 라이브러리이므로 (따라서 이전 버전의 스칼라 및 아크카에 대한 릴리즈를 계속 만듭니다) 더 중요한 요소가 될 것입니다 Play가 스프레이 위에 실행되도록 이식 된 경우. 그래서 스프레이가 쉐이프리스 2 (쉐이프리스 1과 호환되지 않음)에 대한 의존성을 높이기까지는 다소 시간이 걸릴 것으로 예상되며, 그때까지는 스프레이 라우팅의 무결점 빌드를위한 코드를 닫고 가능한 유지 보수의 용이성을 위해 shapeless1 빌드에 대한 것입니다.
FYI : 실제로 스프레이는 더 이상 이런 큰 업데이트를 얻지 못할 것입니다. 대신, 새로운 개발 노력은 대부분 akka-http에 이릅니다. akka-http의 라우팅 부분에서 shapeless2에 대한 의존성이 완전히 제거되었고 DSL은 현재 HLists가 아닌 Scala 튜플을 기반으로합니다. 즉, 문제는 완전히 동일하게 유지되고 이전과 같이 상용구가 생성되어야합니다. – jrudolph
Btw. 왜 그것이 효과가 없을까요? "거시적 수준에서는 가능한 것이지만 AST 표현을 사용할 수있는 방식이 아닙니다."매크로 수준에서 모든 유형에 액세스 할 수 있으므로 원하는 모든 유형 -Y 계산을 수행 할 수 있습니다. – jrudolph
그건 끔찍 하네, 나는 그들이 다시 생각하기를 바란다. HLists는 Scala 튜플보다 훨씬 뛰어납니다.이 차이점에 따라 생산 스프레이 코드가 있습니다. 귀하의 질문에 관해서는, 매크로 수준은 형식에 액세스 할 수 있지만 다른 'FunctionN' 인터페이스 간의 관계를 아는 것은 없습니다. 따라서 매크로는 올바른 'FunctionN'을 얻기 위해 문자열 조작을 사용해야합니다. 그것은 매크로가 그것을 할 수 없다는 것이 아닙니다, 그것은 매크로가 텍스트 프로세서보다 더 나아질 수 없다는 것입니다. – lmm
IMO는 쉐이프리스의 일부 여야합니다. 메일 링에서 (비슷한 질문을 한 번) (https://groups.google.com/d/topic/shapeless-dev/cNQWSE4uAzs/discussion) 후속 조치를 취하지 않았습니다. 따라서이 기능이 필요한 경우 다시 묻는 것이 좋습니다. – jrudolph
나는 혼란 스럽다 ... 이것은 처음부터 거의 형태가없는 부분이었다 ... 나는 무엇을 놓치고 있는가? –
@MilesSabin 먼저 형편없는 것에 감사 드리며 모든 작업을 스칼라를위한 멋진 라이브러리라고 생각합니다! 하지만 "외부 코드 생성"없이는 가능한지 알고 싶었습니다. 일부 유형 수준의 마법을 사용하는 방식과 같이 부정확하게 의미를 부여했기 때문에 어떻게 든 인수를 함수 나 무언가에 재귀 적으로 삽입하거나 다른 방식으로 넣을 수있었습니다 각각의 'FunctionN'에 대해 별도의 인스턴스에 의존하지 않는 방법. 내가 말할 수있는 한, 형형물은 여전히 템플릿을 사용하여 FnFromProduct 인스턴스를 생성합니다. –