복붙노트

[SCALA] 스칼라가 명시 적으로 의존하는 유형을 지원하지 않는 이유 모든 이유?

SCALA

스칼라가 명시 적으로 의존하는 유형을 지원하지 않는 이유 모든 이유?

이 경로 의존적 유형은 나는 거의 모든 스칼라에 경구 또는 AGDA와 같은 언어의 특징을 표현하는 것이 가능하다고 생각하지만, 다른 지역에서 매우 잘하는 것처럼 스칼라 더 명시 적으로 지원하지 않는 이유는 (말 궁금 해요 , DSL을)? 아무것도 I "는 필요 없다"와 같은 누락?

해결법

  1. ==============================

    1.구문 편리 제외하고, 싱글 타입, 경로 의존적 유형과 나는 볼품에 보여주기 위해 노력했습니다로서 스칼라가 종속 입력 놀라 울 정도로 좋은 지원을하고 있음을 암시 값 수단의 조합.

    구문 편리 제외하고, 싱글 타입, 경로 의존적 유형과 나는 볼품에 보여주기 위해 노력했습니다로서 스칼라가 종속 입력 놀라 울 정도로 좋은 지원을하고 있음을 암시 값 수단의 조합.

    의존 유형에 대한 스칼라의 고유 지원은 경로 의존적 유형을 통해입니다. 이러한 형태는 객체 - 통해 선택기 경로에 의존 할 수 있도록 (즉. 부가가치)를 그래프과 같이,

    scala> class Foo { class Bar }
    defined class Foo
    
    scala> val foo1 = new Foo
    foo1: Foo = Foo@24bc0658
    
    scala> val foo2 = new Foo
    foo2: Foo = Foo@6f7f757
    
    scala> implicitly[foo1.Bar =:= foo1.Bar] // OK: equal types
    res0: =:=[foo1.Bar,foo1.Bar] = <function1>
    
    scala> implicitly[foo1.Bar =:= foo2.Bar] // Not OK: unequal types
    <console>:11: error: Cannot prove that foo1.Bar =:= foo2.Bar.
                  implicitly[foo1.Bar =:= foo2.Bar]
    

    내 관점에서, 위의 질문에 대답하기에 충분해야한다 "입니다 스칼라 의존적으로 입력 된 언어를?" 긍정적 인 : 여기에 우리가 그들의 접두사 값에 의해 구별되는 유형이 분명하다.

    그러나, 종종 스칼라가 아니라고 반대 것 내장 함수로 AGDA 또는 COQ 또는 이드리스에있는대로 따라 합계 및 제품 유형이 없기 때문에 "완전히"의존적 언어를 입력합니다. 나는이, 그럼에도 불구하고, 나는 시도하고 스칼라가 훨씬 더 가까이이 다른 언어로 일반적으로 인정되는 것보다 것을 보여 드리겠습니다 어느 정도 펀더멘털 형태의 고정을 반영하고 생각합니다.

    용어에도 불구하고, (또한 시그마 타입이라고도 함)에 의존 합 형태는 단순히 두 번째 값의 타입이 첫 번째 값에 의존하는 값의 쌍이다. 이 스칼라에서 직접 표현할 수있다

    scala> trait Sigma {
         |   val foo: Foo
         |   val bar: foo.Bar
         | }
    defined trait Sigma
    
    scala> val sigma = new Sigma {
         |   val foo = foo1
         |   val bar = new foo.Bar
         | }
    sigma: java.lang.Object with Sigma{val bar: this.foo.Bar} = $anon$1@e3fabd8
    

    사실, 이것은 (실험 -Ydependent 방식의 종류 스칼라 컴파일러 옵션을 통해 이전 또는) 사전 2.10 스칼라에서 '둠 베이커리'에서 탈출 필요한 종속 방식 타입의 인코딩의 중요한 부분이다.

    (PI 유형 일명) 종속 제품 유형 값의 유형에 본질적 기능입니다. 그들은 정적 크기의 벡터의 표현 의존적으로 입력 된 프로그래밍 언어에 대한 다른 포스터 아이들에게 열쇠입니다. 우리는 경로 의존적 유형, 싱글 타입과 암시 적 매개 변수의 조합을 사용하여 스칼라 파이 유형을 인코딩 할 수 있습니다. 먼저 우리는, U 타입으로 타입 T의 값에서 함수를 표현하려고하는 특성을 정의

    scala> trait Pi[T] { type U }
    defined trait Pi
    

    우리는보다이 형식을 사용하는 다형성 방법을 정의 할 수 있습니다

    scala> def depList[T](t: T)(implicit pi: Pi[T]): List[pi.U] = Nil
    depList: [T](t: T)(implicit pi: Pi[T])List[pi.U]
    

    (결과 유형 목록 [pi.U]의 경로 의존적 pi.U 유형의 사용을주의). 타입 T의 값을 주어,이 함수는 특정 T 값에 대응하는 타입의 값 (N 비어 있음) 목록을 반환한다.

    이제 우리가 유지하려는 기능의 관계에 대한 몇 가지 적절한 값 및 암시 증인을 정의 할 수 있습니다,

    scala> object Foo
    defined module Foo
    
    scala> object Bar
    defined module Bar
    
    scala> implicit val fooInt = new Pi[Foo.type] { type U = Int }
    fooInt: java.lang.Object with Pi[Foo.type]{type U = Int} = $anon$1@60681a11
    
    scala> implicit val barString = new Pi[Bar.type] { type U = String }
    barString: java.lang.Object with Pi[Bar.type]{type U = String} = $anon$1@187602ae
    

    그리고 지금 여기에 우리의 파이 형-사용 행동에 기능입니다

    scala> depList(Foo)
    res2: List[fooInt.U] = List()
    
    scala> depList(Bar)
    res3: List[barString.U] = List()
    
    scala> implicitly[res2.type <:< List[Int]]
    res4: <:<[res2.type,List[Int]] = <function1>
    
    scala> implicitly[res2.type <:< List[String]]
    <console>:19: error: Cannot prove that res2.type <:< List[String].
                  implicitly[res2.type <:< List[String]]
                        ^
    
    scala> implicitly[res3.type <:< List[String]]
    res6: <:<[res3.type,List[String]] = <function1>
    
    scala> implicitly[res3.type <:< List[Int]]
    <console>:19: error: Cannot prove that res3.type <:< List[Int].
                  implicitly[res3.type <:< List[Int]]
    

    (참고 여기에 우리가 사용하는 스칼라의 <: <하위-목격 아니라 = 이상 연산자 : res2.type 및 res3.type는 싱글 타입과 우리가 RHS에 확인하는 유형보다는, 따라서 더 정확하기 때문에 =).

    그러나 실제로 스칼라에서 우리는 시그마와 파이 유형을 인코딩하고 우리는 AGDA 또는 이드리스에서와 마찬가지로 거기에서 진행하여 시작하지 않을 것입니다. 대신 우리는 직접 경로 의존적 유형, 싱글 타입과 implicits을 사용합니다. 당신은이 볼품에서 재생하는 방법의 많은 예를 찾을 수 있습니다 크기의 종류, 확장 기록, 종합 HLists, 스크랩 귀하의 상용구를 일반 지퍼 등 등

    내가 볼 수있는 유일한 나머지 이의 파이 유형의 위의 인코딩으로 우리가 의존-에 값하는 표현할 수에의 싱글 타입을 필요로한다는 것이다. 불행히도 스칼라 이것은 기준 유형의 값이 아닌 비 참조 형식의 값에 대해서만 가능하다 (ESP. 예. INT). 스칼라의 타입 검사기가 내부적으로 참조가 아닌 값의 싱글 타입을 나타내며, 그들이 직접 표현할 만드는 실험을 몇이 있었다 :이 수치는 아니지만 고유의 어려움이다. 실제로 우리는 자연수의 상당히 표준 타입 수준의 인코딩 문제를 해결할 수 있습니다.

    어떤 경우에는,이 약간의 도메인 제한이 의존적으로 입력 된 언어와 스칼라의 상태에 대한 이의로 사용할 수 있다고 생각하지 않습니다. 이 경우, 같은 기괴한 결론이 될 것입니다 (천연 숫자 값에 의존 할 수 있습니다) 종속 ML라고 할 수있다.

  2. ==============================

    2.나는 그것이 가정 것이다 (나는 경험에서 알고 완벽을 지원하지만 아직도 매우 편리한 방법으로 COQ 증명 보조에 의존하는 유형을 사용하는 것과 같이) 따라 유형에 하드 정말 아주 고급 프로그래밍 언어 기능 때문에 제대로 - 연습에 복잡성이 기하 급수적으로 파열의 원인이 될 수 있습니다. 그들은 여전히 ​​컴퓨터 과학 연구의 주제입니다.

    나는 그것이 가정 것이다 (나는 경험에서 알고 완벽을 지원하지만 아직도 매우 편리한 방법으로 COQ 증명 보조에 의존하는 유형을 사용하는 것과 같이) 따라 유형에 하드 정말 아주 고급 프로그래밍 언어 기능 때문에 제대로 - 연습에 복잡성이 기하 급수적으로 파열의 원인이 될 수 있습니다. 그들은 여전히 ​​컴퓨터 과학 연구의 주제입니다.

  3. ==============================

    3.나는 스칼라의 경로 의존적 유형은 Σ-유형,하지만 Π-유형을 나타낼 수 있다고 생각합니다. 이:

    나는 스칼라의 경로 의존적 유형은 Σ-유형,하지만 Π-유형을 나타낼 수 있다고 생각합니다. 이:

    trait Pi[T] { type U }
    

    정확히 Π 형이 아닙니다. A, B (x)는 : 정의 Π 형 또는 종속 제품으로 결과 형 즉 ∀x 보편적 정량을 나타내는 인수 값에 의존하는 함수이다. 위의 경우에는, 그러나,하지만 이러한 유형의 몇 가지 가치, 단지 형 T에 따라 달라집니다. A, B (x)는 : 파이 자체가 Σ 형, 실존 정량, 즉 ∃x 특징 부 (trait)이다. 이 경우 객체의 자기 참조 정량화 변수로 작용한다. 암시 적 매개 변수로 전달하면이 유형의 현명한 해결되기 때문에, 그러나, 그것은 일반적인 유형의 기능을 감소시킨다. 스칼라에 따라 제품에 대한 인코딩은 다음과 같이 보일 수 있습니다 :

    trait Sigma[T] {
      val x: T
      type U //can depend on x
    }
    
    // (t: T) => (∃ mapping(x, U), x == t) => (u: U); sadly, refinement won't compile
    def pi[T](t: T)(implicit mapping: Sigma[T] { val x = t }): mapping.U 
    

    여기서 푸는 효과적으로 주어진 속성 객체의 존재를 표현하는 데 사용되는 우리 Σ-종류와 함께 입력 T. 서식하는 모든 값의 특성을 나타내는 방정식을 형성 기대치 t에 대한 정적 제한 필드 X,시키는 능력되면, 로직 된 우리 식 입증하는 정리가 형성된다.

    보조 노트에, 실제 경우에 정리가 자동으로 코드에서 파생이나 노력의 상당한 양의없이 해결 될 수없는 지점까지 매우 사소 할 수있다. 하나는 심지어 실제로 그것을 증명 영원히 반복하거나 예외를 던지는없이 구현하는 것은 불가능 서명을 찾기 위해,이 방법 리만 가설을 수립 할 수 있습니다.

  4. ==============================

    4.문제는, 내 의견으로는, 더 직접적으로 의존적 입력 기능을 사용하여 약이었다 어떤 스칼라 이벤트보다 더 직접적인 의존 입력 방식을 가지고있는 이점이 될 것입니다. 현재 답변 유형 이론적 인 수준에서 질문을 주장하려고합니다. 나는 그것을 더 실용적인 스핀을 넣어합니다. 사람들은 스칼라 언어에 의존하는 형태의 지원 수준에 나누어집니다 이유를 설명 할 수있다. 우리는 마음에서 다소 다른 정의가있을 수 있습니다. (하나가 바로 말할 하나는 잘못하지 말 것).

    문제는, 내 의견으로는, 더 직접적으로 의존적 입력 기능을 사용하여 약이었다 어떤 스칼라 이벤트보다 더 직접적인 의존 입력 방식을 가지고있는 이점이 될 것입니다. 현재 답변 유형 이론적 인 수준에서 질문을 주장하려고합니다. 나는 그것을 더 실용적인 스핀을 넣어합니다. 사람들은 스칼라 언어에 의존하는 형태의 지원 수준에 나누어집니다 이유를 설명 할 수있다. 우리는 마음에서 다소 다른 정의가있을 수 있습니다. (하나가 바로 말할 하나는 잘못하지 말 것).

    이것은 설정하는 것이 얼마나 쉬운 질문에 대답하기위한 시도하지 않습니다 이드리스 같은으로 스칼라 (나는 아주 열심히 상상) 또는 라이브러리를 작성하는 기능처럼 이드리스에 대한 직접적인 지원을 제공 (싱글의 시도 같은 것은 하스켈에 있어야합니다).

    대신에, 나는 스칼라와 이드리스 같은 언어 사이의 실제적인 차이를 강조하고 싶다. 값을 입력 레벨 표현에 대한 코드 비트는 무엇입니까? 이드리스 스칼라는 매우 다른 코드를 사용, 동일한 코드를 사용합니다.

    (유사 하스켈에) 스칼라 식 레벨 계산의 인코딩을 많이 할 수 있습니다. 이것은 무형의 같은 라이브러리가 표시됩니다. 이 라이브러리는 정말 인상적이고 영리한 트릭을 사용하여이 작업을 수행. 그러나, 그들의 식 레벨 코드 (현재) 값 수준의 표현에서 매우 다르다 (나는 그 차이가 하스켈에 어느 정도 근접하도록 찾기). 이드리스는 AS가 타입 레벨 값 레벨 표현을 사용할 수있다.

    명백한 이점은 코드 재사용 (당신이 코드 유형 레벨 표현 할 필요가 없습니다 것입니다 별도로 값 수준에서 당신은) 두 곳에서 그들을 필요로하는 경우. 그것은하는 방법 쉽게해야한다 쓰기 값 레벨 코드. (성능 비용을 언급하지 않기 위하여) 싱글 같은 해킹 처리하지에 쉽게해야합니다. 당신은 당신이 한 가지를 배울 두 가지를 배울 필요가 없습니다. 실용적인 수준에서, 우리는 적은 수의 개념을 필요로 끝낸다. 유형의 동의어를 입력 가족, 기능, ... 방법에 대한 단지 기능? 제 생각에는,이 통합 혜택은 훨씬 더 깊게 및 구문 편리 이상입니다.

    검증 된 코드를 살펴 보자. 보다: https://github.com/idris-lang/Idris-dev/blob/v1.3.0/libs/contrib/Interfaces/Verified.idr 모나드 / 펑터 / 실용적 법률과 유형 검사기를 검증 교정 교정은 모나드 / 펑 / 실용적이 아니라 일부의 실제 인코딩에 대해 구현되어 동일하거나 동일하지 수있다 동등한 레벨을 입력. 가장 큰 문제는 우리가 무엇을 증명하고있다?

    내가 영리 인코딩 기법을 사용하여 수행 같은 캔 (스칼라에 대한 하스켈 버전 다음, 내가 보지 못한 하나를 참조하십시오) https://blog.jle.im/entry/verified-instances-in-haskell.html https://github.com/rpeszek/IdrisTddNotes/wiki/Play_FunctorLaws 유형은 그래서 법률을보기는 어렵다 것을 복잡 제외하고는 값 수준의 표현 수준의 일을 입력 (자동하지만 여전히) 변환되고 당신은뿐만 아니라 그 변환을 신뢰해야합니다. 좀 컴파일러 행동의 목적 등을 무시이 모든 오류의 여지가있다 증거 조수.

    (2018년 8월 10일 편집) 증거 지원에 대한 이야기, 여기 이드리스와 스칼라 사이에 또 ​​다른 큰 차이가있다. 분기 증거를 쓰는 것을 방지 할 수 있습니다 스칼라 (또는 하스켈)에 아무것도 없다 :

    case class Void(underlying: Nothing) extends AnyVal //should be uninhabited
    def impossible() : Void = impossible()
    

    이드리스 컴파일에서이 같은 코드를 방지 총 키워드를 가지고있다.

    의 Unify 값과 (하스켈 싱글 같은) 식 레벨 코드에 대한 시도가 의존하는 유형의 스칼라의 지원을위한 흥미로운 테스트가 될 것이라고 스칼라 라이브러리입니다. 이러한 라이브러리 때문에 경로에 의존하는 유형의 스칼라에서 훨씬 더 잘 할 수 있습니까?

    나는 그 질문을 나 자신에 대답 스칼라 너무 새로운입니다.

  5. from https://stackoverflow.com/questions/12935731/any-reason-why-scala-does-not-explicitly-support-dependent-types by cc-by-sa and MIT license