여기에 몇 가지 문제가 있습니다. 첫 번째는 hlist의 정적 유형에 Option
대신 Some
이 있으므로 uuu
이 options
에 매핑 될 수 있음을 증명해야한다는 증거가 Mapper
임을 알 수 없습니다. 이 문제를 해결하는 가장 좋은 방법은 반환하는 스마트 Some
생성자를 정의하는 것입니다 Option
:
def some[A](a: A): Option[A] = Some(a)
val options = some(1) :: some("A") :: some(3.5) :: HNil
또한 원래 options
에 유형 주석을 추가하거나 Some
대신 Option
작업을 uuu
을 변경할 수 있습니다 (이 될 것입니다 더 안전하지만 아마도 목표가 무엇이든간에 덜 유용 할 것입니다.)
이제 코드가 인으로 컴파일되지만, 이는 Any
이 스칼라에서 kind-polymorphic이라는 다소 기괴한 사실 때문입니다. 일반적으로 F ~> G
이있는 경우 F
및 G
은 단일 유형 매개 변수를 취하는 유형 생성자 여야합니다 (예 : Option ~> List
. Any
은 형식 매개 변수를 사용하지 않고 작동하지만 스칼라 언어에 대한 이상한 사실 (Any
은 Nothing
과 함께 kind-polymorphic이며 형식이 필요한 슬롯, 형식 생성자와 하나의 매개 변수, 12 개의 매개 변수가있는 유형 생성자 등).
그래야 컴파일됩니다.하지만 Any :: Any :: Any :: HNil
을 반환하기 때문에 꽤 쓸모가 없습니다. 당신은 shapeless.Id
과 자연의 변화에 Any
을 대체하여이 문제를 해결할 수 있습니다
import shapeless._, shapeless.poly.~>
def some[A](a: A): Option[A] = Some(a)
val options = some(1) :: some("A") :: some(3.5) :: HNil
object uuu extends (Option ~> Id) {
def apply[T](l: Option[T]): T = l.get
}
options.map(uuu)
Id
이 type Id[+T] = T
-i.e.으로 정의된다, 그것은 당신에게 풀어 유형을 제공 신원 타입 생성자입니다.
모두 컴파일이 버전은 다시 유용하게 형식의 결과를 제공하지만, 당신이 (런타임) None
있습니다와 hlist
오버 요소를하게되면, 이후는, 당신이 NoSuchElementException
를 얻을 수 있습니다, 아직 정말 안전하지. 이 문제를 해결하기위한 방법이 전혀 없습니다. Option ~> Id
에서 Some ~> Id
으로 어떻게 든 기본값을 제공하는 등 운영의 성격이 크게 바뀝니다.
트래비스는 '스칼라에서 어떤 종류의 다형성이 있습니까?' –
@KevinMeredith 글쎄, 그 단락은 기초를 설명합니다.좀 더 구체적으로'def foo [F [_, _, _]] (f : F [Int, Int, Int]) = f'을 정의하고'foo [Any] (1)'를 시도하십시오. –