경로 의존 유형의 빠른 해석

Scala는 오랫동안 경로 의존 유형의 개념이 있었는데 Scala 3에서 이 개념은 형식화된 유형 시스템에 사용되었다(참조: DOT Calculus.그러나 오랫동안 나처럼 경로 의존 유형이 범형에게 어떤 실질적인 이익을 가져다 주었는지 생각하고 있었을 것이다.
경로 의존 형식은 실행할 때만 알 수 있는 형식을 처리하는 데 매우 유용합니다.

C. 시간 및 경로 관련 유형


최근에 저는 Scala와 C가 상호작용을 하도록 코드를 작성해 왔습니다. 이렇게 해서 저는 독특한 도전에 부딪혔습니다.그 중 하나는 사용자가 필요할 때 C 귀속에서 사용할 수 있도록 유형을 정의하는 것이다.time_t는 c표준 라이브러리의 일부이지만 그 실현은 이 라이브러리를 실현하는 라이브러리에서 이루어진다.i386 리눅스(i386은 32비트 Intel arch) 기기에서 time_t는 JVMtime_t에 해당하고, i386 Midnight BSD에서는 JVMLong에 해당한다.내 라이브러리의 C 바인딩은 유형을 기반으로 하기 때문에 심각한 문제가 있습니다.
  • 만약에 Inttime_t로 정의한다면 나의 라이브러리는 자정 BSD 기계
  • 에서만 사용할 수 있다
  • 만약에 type time_t=Inttime_t로 정의한다면 제 라이브러리는 Linux 기기에서만 사용할 수 있습니다
  • 만약에 내가 type time_t=Longtime64_t를 정의한다면 나의 라이브러리는 이 두 운영체제에서 모두 사용할 수 있지만 사용자 코드가 한 운영체제에 잠겨서 그들은 어떤 운영체제를 개발할지 걱정할 수밖에 없다.
  • 실행할 때 형식만 정의할 수 있다면...하면, 만약, 만약...
    type time_t = if os == Linux then Long 
    else if os == MidnightBSD then Int 
    else Nothing
    
    그럼 난 괜찮아!!프로그램이 실행될 때 경로에 따라 정의된 형식을 쓸 수 있는 방법이 있다면...
    읊다, 읊조리다경로 의존 유형!!

    일이 순조롭게 진행되도록 하다


    나는 나의 사용자를 만족시킬 수 있는 몇 가지 특징이 있다.우선, 나는 time_t의 원형이 필요하다.
    trait time_t_proto:
      type time_t
      val time_t_integral: Integral[time_t]
      implicit class time_t_ops(time_t: time_t) 
        extends time_t_integral.IntegralOps(time_t)
      implicit class time_t_ord(time_t: time_t) 
        extends time_t_integral.OrderingOps(time_t)
    
    Scala는 컴파일할 때 time_t 이 버전을 사용할 것입니다. 이 버전에서는 time_t 형식 클래스를 실행할 때 time_t 정의하기로 약속합니다.그리고 우리는 컴파일러가 Integraltime_t 스텔스 클래스를 통해 + 연산자나 < 연산자 등의 기능을 확장time_t_ops하는 방법을 알려준다.이것은 사용자가 이 유형에 대해 기본 정렬과 산술을 할 수 있도록 합니다. time_t_ord 또는 Int 처럼, 컴파일할 때 형식이 알 수 없지만.
    이제 구현이 필요합니다.
    trait time_t_impl[U](using val time_t_integral: Integral[U]) 
      extends time_t_proto:
      type time_t = U
    
    이것은 실현된 것 같지는 않지만, 이렇게 작성된 것이기 때문에, 대형적인arch에 특정된Long 유형에 혼합할 수 있다.
    trait Platform extends time_t_proto
    
    object PlatformI386 extends Platform, time_t_impl[Int]
    object PlatformX64 extends Platform, time_t_impl[Long]
    
    val platform: Platform = if arch == i386 then PlatformI386 
    else if arch == x86_64 then PlatformX64
    else ???
    
    우리는 마침내 최종 결과를 얻었다.Platform와impl에 사용되는 디자인은 이 원형의 여러 개와 플랫폼에 특정한 C 유형(예를 들어 time_t_proto에 사용되는impl 유형을 허용한다.또한 수많은 컴퓨팅 플랫폼에 귀속을 신속하고 쉽게 정의할 수 있습니다.마지막으로 실행할 때 적당한 dev_t 구현을 선택하고 이를 Platform 값에 분배함으로써 사용자가 플랫폼에 특정한 유형을 사용할 수 있고 플랫폼에 특정한 방식으로 쓸 필요가 없다.
    결과적으로 사용자는 바인딩을 다음과 같이 정의할 수 있습니다.
    import platform.time_t
    def time(timer: Ptr[time_t]): time_t = bind
    
    어느 컴퓨터에 접근하든지 간에 이러한 귀속은 작동할 것이다. 왜냐하면 적절하고 경로에 의존하는 유형 정보는 실행할 때 불러오고 사용되며, 컴파일링할 때 컴파일러에게 완전한 유형 안전을 확보하기 위해 충분한 정보와 보장을 제공하기 때문이다.
    물론 사용자가 원한다면 플랫폼에 특정한 코드를 작성할 수 있다.
    import PlatformX64.time_t
    def time(timer: Ptr[time_t]): time_t = bind
    
    위 코드는 잘 작동하고 있습니다. 위 코드의time t는 알 수 없는 형식이 아니라 컴파일할 때platform로 이해됩니다.그러나 이 코드는 더 이상 어디에도 적용되지 않을 것이며 이것은 JVM을 위해 코드를 작성하는 데 큰 매력이 될 것이다.

    이것은 범형을 통해 실현할 수 있습니까?


    요컨대, 없다. 우리는 같은 작업량으로 범형을 사용해서 같은 효과를 낼 수 없다.우리는 범형으로 상술한 기능을 실현하려고 시도할 수 있지만, 범형은 우리를 실패하게 할 것이다.proto trait 및 Platform trait를 수정하여 삽입식 대신 일반형Long을 사용한다고 가정합니다.
    trait time_t_proto[time_t]:
      val time_t_integral: Integral[time_t]
      implicit class time_t_ops(time_t: time_t) 
        extends time_t_integral.IntegralOps(time_t)
      implicit class time_t_ord(time_t: time_t) 
        extends time_t_integral.OrderingOps(time_t)
    
    trait time_t_impl[U](using val time_t_integral: Integral[U]) 
      extends time_t_proto[U]
    
    trait Platform[A] extends time_t_proto[A]
    
    object PlatformI386 extends Platform[Int], time_t_impl[Int]
    object PlatformX64 extends Platform[Long], time_t_impl[Long]
    
    val platform: Platform[?] = if arch == i386 then PlatformI386 
    else if arch == x86_64 then PlatformX64
    else ???
    
    위의 코드는 틀림없이 컴파일될 것입니다. 그러나 사용자는 어떻게 type time_t 유형을 얻을 수 있습니까?이곳의 time_t 유형은 정확한 유형에 대응하지만, 우리 사용자에게는 사용할 수 없습니다.더 심각한 것은 우리의 코드가 더욱 복잡해졌다는 것이다. ? 진정으로 우리가 원하는 방식으로 일을 하기 위해서는 많은 일을 해야만 C와 연결된 모든 부분을 관리하는 god의 대상이 될 수 있다.

    요컨대


    경로 의존 유형은 Scala의 강력한 기능이지만 지역사회에서 잘 이해되지 않는다.나는 플랫폼의 특정 유형(예를 들어 CPlatform)의 문제가 경로 의존 유형의 필요성과 그들이 어떤 상황에서 범주형을 어떻게 초월하는지 설명하기 쉽다고 믿는다.

    좋은 웹페이지 즐겨찾기