Shapeless에서 Nat 유형의 한계


151

형태가없는 경우 Nat 유형은 유형 수준에서 자연수를 인코딩하는 방법을 나타냅니다. 예를 들어 고정 크기 목록에 사용됩니다. 유형 레벨에서 계산을 수행 할 수도 있습니다. 예를 들어 N요소 목록에 요소 목록을 추가하고 K컴파일시 알려진 목록을 가져와 N+K요소 를 갖습니다 .

이 표현이 많은 수 (예 : 10000002 53)를 표현할 수 있습니까 , 아니면 Scala 컴파일러가 포기하게됩니까?


21
작년 Miles의 NE Scala 프레젠테이션 은이 질문을 다루고 있으며 짧은 대답은 싱글 톤 유형을 사용하여 Scala의 유형 수준에서 또는 최소한 2.10에서 큰 숫자를 표현할 수는 있지만 그만한 가치는 없을 것 입니다. Shapeless 2.0은 현재 교회 인코딩을 여전히 사용하므로 컴파일러가 포기하기 전에 1,000 정도가됩니다.
트래비스 브라운

3
오늘 후반에 조금 더 문맥으로 답을 쓰려고 노력할 것입니다. 참고로 더 큰 유형 레벨 번호가 필요한 경우 정수 싱글 톤 유형으로 작업하는 것은 그리 어렵지 않습니다. 예를 들어 여기의 블로그 게시물 또는 Shapeless싱글 톤 기능을 참조하십시오 .
Travis Brown

2
큰 유형 수준의 숫자에 대해 산술을 수행하려면 연결된 비트 목록으로 구현하는 것이 좋습니다.
Karol S

1
@KarolS 그 전략을 구현했습니다! 누군가가 관심이 있다면 무형에 기여하게되어 기쁩니다. 비록 누군가가 stackoverflow.com/questions/31768203/을
beefyhalo

2
stackoverflow.com/questions/31768203/… 이 해결 된 것처럼 보이 므로 코드에 기여하고 자신의 답변으로 질문을 닫을 수 있습니까?
Andriy Kuba

답변:


17

나는 스스로 시도 할 것이다. Travis Brown 또는 Miles Sabin의 더 나은 답변을 기꺼이 받아들입니다.

Nat는 현재 많은 수를 나타내는 데 사용할 수 없습니다

Nat의 현재 구현에서 값은 중첩 된 shapeless.Succ [] 유형의 수에 해당합니다.

scala> Nat(3)
res10: shapeless.Succ[shapeless.Succ[shapeless.Succ[shapeless._0]]] = Succ()

따라서 숫자 1000000을 나타내려면 1000000 레벨 깊이로 중첩 된 유형이 있어야 스칼라 컴파일러가 확실히 폭발 할 것입니다. 현재 한계는 실험에서 약 400으로 보이지만 합리적인 컴파일 시간에는 50 미만으로 유지하는 것이 가장 좋습니다.

그러나 계산을 원하지 않는 경우 큰 정수 또는 다른 값을 유형 수준으로 인코딩하는 방법이 있습니다 . 내가 아는 한 당신이 할 수있는 유일한 것은 그들이 같은지 여부를 확인하는 것입니다. 아래를 참조하십시오.

scala> type OneMillion = Witness.`1000000`.T
defined type alias OneMillion

scala> type AlsoOneMillion = Witness.`1000000`.T
defined type alias AlsoOneMillion

scala> type OneMillionAndOne = Witness.`1000001`.T
defined type alias OneMillionAndOne

scala> implicitly[OneMillion =:= AlsoOneMillion]
res0: =:=[OneMillion,AlsoOneMillion] = <function1>

scala> implicitly[OneMillion =:= OneMillionAndOne]
<console>:16: error: Cannot prove that OneMillion =:= OneMillionAndOne.
       implicitly[OneMillion =:= OneMillionAndOne]
                 ^

예를 들어 Array [Byte]에서 비트 연산을 수행 할 때 동일한 배열 크기를 적용하는 데 사용할 수 있습니다.


이 답변을 보았습니다. +1, 이것은 좋은 예입니다. 그것의 가치가 당신이 비록 주목할 수있다 예를 들면 무형의 같은 종류의 클래스를 제공 ops.nat.Sum즉, (그들은 단지 매크로에 의해 제공되어야하는 것)이 타입 수준의 정수가 특정 금액 등을 한 것으로 목격 할 것입니다.
Travis Brown

1
다음Concat매크로를 통해 두 가지 유형 수준 문자열을 연결할 수 있는 유형 클래스 의 예입니다 . 타입 레벨 정수를 합산하는 타입 클래스는 아마도 매우 비슷할 것입니다.
Frank S. Thomas

5

Shapeless Nat는 교회 인코딩을 사용하여 유형 수준에서 자연수를 인코딩합니다. 다른 방법은 비트의 타입 레벨 HList로 내츄럴을 표현하는 것입니다.

이 솔루션을 형태없는 스타일로 구현 하는 고밀도 를 확인하십시오 .

나는 한동안 그것을 연구하지 않았으며 Lazy스칼라가 포기할 때 여기 저기 형태 가 없어야하지만 개념은 확실합니다. :)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.