수색…


비고

하스켈의 강점 중 하나는 타입 시스템에서 타입 도메인을 사용하여 문제 도메인의 일부를 모델링 할 수있는 능력입니다. 그렇게하는 과정에서 종종 매우 복잡한 유형을 접하게됩니다. 이러한 유형 (즉, 이러한 유형의 값을 가진 프로그램)을 작성할 때 모든 유형의 '저글링'이 거의 불가능해질 수 있습니다. GHC 7.8부터는 형식화 된 구멍이라는 새로운 구문 기능이 있습니다. 형식화 된 구멍은 핵심 언어의 의미를 변경하지 않습니다. 그들은 순수하게 프로그램을 작성하는 데 도움을주기위한 것입니다.

입력 된 구멍에 대한 자세한 설명과 입력 된 구멍의 디자인에 대한 설명은 Haskell 위키를 참조하십시오.


입력 된 구멍 에 관한 GHC 사용자 안내서의 섹션.

입력 된 구의 구문

입력 된 구멍은 표현식 컨텍스트에서 범위에없는 단일 밑줄 ( _ ) 또는 유효한 하스켈 식별자입니다. 입력 된 구멍이 존재하기 전에이 두 가지 모두 오류를 유발하므로 새로운 구문이 이전 구문을 간섭하지 않습니다.

입력 된 구멍의 동작 제어

입력 된 구멍의 기본 동작은 입력 된 구멍이있을 때 컴파일 타임 오류를 생성하는 것입니다. 그러나 행동을 미세 조정할 수있는 몇 가지 플래그가 있습니다. 이러한 플래그는 다음과 같이 요약됩니다 ( GHC trac ).

기본적으로 GHC는 입력 된 구멍을 입력하고 입력 된 구멍을 만났을 때 컴파일 오류를 생성합니다.

-fdefer-type-errors 또는 -fdefer-typed-holes 을 사용하면 구멍 오류가 경고로 변환되고 평가시 런타임 오류가 발생합니다.

-fwarn-typed-holes 경고 플래그는 기본적으로 설정됩니다. -fdefer-type-errors 또는 -fdefer-typed-holes 하지 않으면이 조건에서 입력 된 구멍이 오류 -fdefer-typed-holes 플래그는 작업 없음입니다. 지연 플래그 중 하나가 사용 가능하면 (유형이 지정된 홀 오류를 경고로 변환하는 경우) -fno-warn-typed-holes 플래그는 경고를 사용 불가능하게합니다. 이는 컴파일이 자동으로 성공하고 구멍을 평가하면 런타임 오류가 발생 함을 의미합니다.

타이핑 된 구멍의 의미

타입 구멍의 값은 타입 undefined 된 구멍이 컴파일 타임 에러를 유발하지만 간단히 말해서 undefined 않았다고 말할 수 있으므로, 값을 할당 할 필요는 없습니다. 그러나 입력 된 구멍 (활성화 된 경우)은 입력 된 구멍의 이름, 추정 된 가장 일반적인 형식 및 모든 로컬 바인딩의 형식을 나타내는 컴파일 시간 오류 (지연된 형식 오류가있는 경고)를 생성합니다. 예 :

Prelude> \x -> _var + length (drop 1 x)

<interactive>:19:7: Warning:
    Found hole `_var' with type: Int
    Relevant bindings include
      x :: [a] (bound at <interactive>:19:2)
      it :: [a] -> Int (bound at <interactive>:19:1)
    In the first argument of `(+)', namely `_var'
    In the expression: _var + length (drop 1 x)
    In the expression: \ x -> _var + length (drop 1 x)

위와 같이 GHCi repl에 입력 된 표현식에 입력 된 구멍의 경우 입력 된 표현식의 유형도보고 it (여기서 유형 [a] -> Int ).

입력 된 구멍을 사용하여 클래스 인스턴스 정의

입력 된 구멍을 사용하면 대화식 프로세스를 통해 함수를 쉽게 정의 할 수 있습니다.

클래스 인스턴스 Foo Bar ( Foo 인스턴스가 필요한 일부 다형성 라이브러리 함수와 함께 사용하기 위해 사용자 정의 Bar 유형 용)를 정의한다고 가정 해보십시오. 이제 전통적으로 Foo 의 문서를 살펴보고, 정의 할 필요가있는 메서드를 파악하고, 형식을 조사합니다. 그러나 형식화 된 구멍을 사용하면 실제로 건너 뛸 수 있습니다!

먼저 더미 인스턴스를 정의하십시오.

instance Foo Bar where

컴파일러는 이제 불평 할 것이다.

Bar.hs:13:10: Warning:
No explicit implementation for
  ‘foom’ and ‘quun’
In the instance declaration for ‘Foo Bar’

좋습니다, 그래서 우리는 foom 위해 foom 을 정의 할 필요가 Bar . 그러나도 있어야하는 것이 무엇인가? 다시 우리는 문서를보기에는 너무 게으르다. 컴파일러에게 물어 보자 :

instance Foo Bar where
  foom = _

여기서 우리는 입력 된 구멍을 간단한 "문서 쿼리"로 사용했습니다. 컴파일러 출력

Bar.hs:14:10:
    Found hole ‘_’ with type: Bar -> Gronk Bar
    Relevant bindings include
      foom :: Bar -> Gronk Bar (bound at Foo.hs:4:28)
    In the expression: _
    In an equation for ‘foom’: foom = _
    In the instance declaration for ‘Foo Bar’

컴파일러가 클래스 유형 변수를 이미 인스턴스화하려는 구체 유형 Bar 채우는 방법에 유의하십시오. 이렇게하면 클래스 문서에서 발견되는 다형성보다 훨씬 쉽게 서명을 이해할 수 있습니다. 특히 다중 매개 변수 유형 클래스와 같은 더 복잡한 메소드를 다루는 경우 더욱 그렇습니다.

하지만 Gronk 대체 Gronk ? 이 시점에서 Hayoo 에게 물어 보는 것이 좋습니다. 그러나 우리는 여전히 그것을 벗어날 수 있습니다 : 맹목적인 추측으로, 우리는 이것이 형식 생성자 일뿐만 아니라 단일 값 생성자라고 가정합니다. 즉, 어떤 식 으로든 Gronk a 값을 생성하는 함수로 사용될 수 있습니다. 그래서 우리는 시도

instance Foo Bar where
  foom bar = _ Gronk

우리가 운이 좋다면, Gronk 은 실제로 값이고, 컴파일러는 이제

    Found hole ‘_’
      with type: (Int -> [(Int, b0)] -> Gronk b0) -> Gronk Bar
    Where: ‘b0’ is an ambiguous type variable

좋습니다. 그게 추한 것입니다. 처음에는 Gronk 이 두 가지 논점을 가지고 있으므로 시도를 다듬을 수 있습니다.

instance Foo Bar where
  foom bar = Gronk _ _

그리고 지금 이것은 꽤 분명합니다.

    Found hole ‘_’ with type: [(Int, Bar)]
    Relevant bindings include
      bar :: Bar (bound at Bar.hs:14:29)
      foom :: Bar -> Gronk Bar (bound at Foo.hs:15:24)
    In the second argument of ‘Gronk’, namely ‘_’
    In the expression: Gronk _ _
    In an equation for ‘foom’: foom bar = Gronk _ _

예를 들어 bar 값을 해체하여 추가 진행할 수 있습니다 (구성 요소는 Relevant bindings 섹션에 유형과 함께 표시됨). 올바른 정의가 무엇인지 완전히 명확한 시점이 종종 있습니다. 사용 가능한 모든 인수와 유형이 지그 소 퍼즐과 같이 결합되어 있기 때문입니다. 또는 정의가 불가능 하고 왜 그런지 알 수 있습니다.

이 모든 것은 인터랙티브 편집이 가능한 편집기에서 가장 잘 작동합니다 (예 : haskell-mode를 사용하는 Emacs). 그런 다음 IDE에서 마우스 오버 값 쿼리와 마찬가지로 입력 된 구멍을 사용하여 해석 된 동적 명령형 언어를 사용할 수 있지만 모든 제한은 없습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow