하단 유형에 함수 매개 변수 유형으로 사용 사례가 있습니까?


12

함수에 반환 유형이 ⊥ ( bottom type )이면 반환되지 않습니다. 예를 들어 상당히 일반적인 상황에서 나가거나 던질 수 있습니다.

함수에 ⊥ 유형의 매개 변수가있는 경우에는 (안전하게) 호출 할 수 없습니다. 그러한 함수를 정의 할 이유가 있습니까?

답변:


17

또는 빈 유형 의 정의 속성 중 하나는 모든 유형 A에 대해 A 기능이 있다는 것 입니다. 실제로는 고유 한 기능이 있습니다. 따라서이 기능이 표준 라이브러리의 일부로 제공되는 것이 상당히 합리적입니다. 종종 그것은 같은 것 입니다. (하위 유형을 가진 시스템에서, 이것은함으로써 간단하게 처리 할 수 모든 유형의 하위 유형합니다. 그런 다음 암시 적 변환입니다 . 또 다른 관련 접근 방식입니다 정의 α . α 간단하게 할 수 인스턴스화 모든 유형을.)Aabsurdabsurd α.α

당신이 생산하는 것이 기능을 활용할 수 있습니다 무엇 때문에 당신은 확실히 같은 기능 또는 동등한를 갖고 싶어 . 예를 들어, 합계 유형 E+A 가 있다고 가정 해 봅시다 . 나는 그것에 대한 사례 분석을하고 E 경우에는 throw:E 사용하여 예외를 던질 것 입니다. 에서 A 경우, 내가 사용합니다 f:AB . 전반적으로 B 유형의 값을 원 하므로 B 로 바꾸려면 무언가를해야합니다 . 그것이 내가 absurd할 수있는 일입니다.

즉, A 의 기능을 직접 정의해야 할 이유는 많지 않습니다 . 정의에 따르면 반드시의 인스턴스 일 것입니다 absurd. 그러나 absurd표준 라이브러리에서 제공하지 않거나 형식 검사 / 추론을 지원하는 형식 특수 버전을 원할 경우 그렇게 할 수 있습니다 . 그러나 A 와 같은 유형으로 인스턴스화 되는 함수를 쉽게 생성 할 수 있습니다 .A

그러한 함수를 작성할 이유가 많지는 않지만 일반적으로 여전히 허용 되어야합니다 . 한 가지 이유는 코드 생성 도구 / 매크로를 단순화하기 때문입니다.


따라서 이것은 (x ? 3 : throw new Exception())분석 목적으로 비슷한 것이 대체 더 유사한 것으로 대체 됨을 의미합니다 (x ? 3 : absurd(throw new Exception())).
bdsl

하위 유형이 없거나 α 로 정의하지 않은 경우 . α 이면 전자는 check를 입력하지 않고 후자는 type을 입력합니다. 하위 타이핑을 사용하면 예를 들어 암시 적으로 삽입됩니다. 물론, α 로 정의하는 정의를 내부에 넣을 수 있습니다. α 는 할 것이다. α.αabsurdabsurdthrowα.α
Derek Elkins가 SE를

6

함수에 대해 말한 것을 추가하기 absurd: ⊥ -> a위해이 함수가 실제로 유용한 위치에 대한 구체적인 예가 있습니다.

s를 포함하는 모양의 노드와 잎이 Free f a있는 일반적인 트리 구조를 나타내는 Haskell 데이터 유형 을 고려하십시오 .fa

data Free f a = Op (f (Free f a)) | Var a

이 나무는 다음 기능으로 접을 수 있습니다.

fold :: Functor f => (a -> b) -> (f b -> b) -> Free f a -> b
fold gen alg (Var x) = gen x
fold gen alg (Op x) = alg (fmap (fold gen alg) x)

간단히,이 작업 alg은 노드와 gen나뭇잎에 배치됩니다.

이제 요점 : 모든 재귀 데이터 구조는 고정 소수점 데이터 유형을 사용하여 표현할 수 있습니다. Haskell에서 이것은 (예 를 들어 functor 외부에 잎이없는 모양의 노드가있는 나무)로 Fix f정의 할 수 있습니다 . 전통적으로이 구조는 다음과 같이 접 힙니다 .type Fix f = Free f ⊥ffcata

cata :: Functor f => (f a -> a) -> Fix f -> a
cata alg x = fold absurd alg x

나무에 어떤 잎도 가질 수 없기 때문에 (⊥ 외에 다른 주민이 없기 때문에 undefined) gen이 접힘에 대해 사용할 수 없으며 그것을 absurd보여줍니다!


2

하단 유형은 다른 모든 유형의 하위 유형이므로 실제로 매우 유용 할 수 있습니다. 예를 들어, NULL이론적 인 형식 안전 버전 C의 형식은 다른 모든 포인터 형식의 하위 형식이어야합니다. 그렇지 않으면 예상 한 NULL위치를 반환 할 수 없습니다 char*. 마찬가지로 undefined이론적 인 형식 안전 JavaScript의 유형은 언어에서 다른 모든 유형의 하위 유형이어야합니다.

exit()throw()IntIntexit()

TST


3
NULL빈 유형 인 ⊥과는 다른 단위 유형이 아닌가?
bdsl

나는 유형 이론에서 ≺이 무엇을 의미하는지 잘 모르겠습니다.
bdsl

1
@bdsl 여기서 곡선 연산자는 "하위 유형"입니다. 그것이 표준인지 확실하지 않습니다. 교수님이 사용한 것입니다.
Draconis

1
@ gnasher729 사실이지만 C도 특히 형식 안전하지 않습니다. 정수를 캐스트 할 수 없다면 void*모든 포인터 유형에 사용할 수있는 특정 유형이 필요합니다.
Draconis


2

내가 생각할 수있는 용도가 하나 있는데, 이는 Swift 프로그래밍 언어의 개선으로 간주 된 것입니다.

Swift에는 maybeMonad, Optional<T>또는 철자가 T?있습니다. 상호 작용하는 방법에는 여러 가지가 있습니다.

  • 다음과 같은 조건부 언 래핑을 사용할 수 있습니다.

    if let nonOptional = someOptional {
        print(nonOptional)
    }
    else {
        print("someOptional was nil")
    }
    
  • 당신은 사용할 수 있습니다 map, flatMap값을 변환

  • 강제 랩핑 해제 연산자 ( !유형의 (T?) -> T)가 컨텐츠를 강제로 랩 해제합니다. 그렇지 않으면 충돌이 발생합니다.
  • nil-coalescing 연산자 ( ??유형의 (T?, T) -> T)는 값을 가져 오거나 그렇지 않으면 기본값을 사용합니다.

    let someI = Optional(100)
    print(someI ?? 123) => 100 // "left operand is non-nil, unwrap it.
    
    let noneI: Int? = nil
    print(noneI ?? 123) // => 123 // left operand is nil, take right operand, acts like a "default" value
    

불행히도 "unwrap or throw an error"또는 "custom wrap with a custom error message"라는 간결한 방법은 없었습니다. 같은 것

let someI: Int? = Optional(123)
let nonOptionalI: Int = someI ?? fatalError("Expected a non-nil value")

fatalError유형이 있기 때문에 컴파일되지 않습니다 () -> Never( ()is Void, Swift '단위 유형, NeverSwift의 하단 유형). 그것을 호출하면 의 올바른 피연산자로 예상되는 것과 Never호환되지 않습니다 .T??

이 문제를 해결하기 위해 Swift Evolution propsoal- SE-0217"Unwrap or Die"연산자 가 작성되었습니다. 그것은했다 궁극적으로 거부 하지만, 제작에 관심을 제기 Never모든 유형의 하위 유형해야합니다.

Never모든 유형의 하위 유형이 되었으면 이전 예제를 컴파일 할 수 있습니다.

let someI: Int? = Optional(123)
let nonOptionalI: Int = someI ?? fatalError("Expected a non-nil value")

의 호출 사이트에 ??유형 (T?, Never) -> T이 있으며의 (T?, T) -> T서명 과 호환 되기 때문 입니다 ??.


0

Swift는 "Never"유형을 가지고 있으며 이는 아래 유형과 매우 유사합니다.

이것은 클래스와 함께 특정 함수를 가져야하는 언어의 유형 시스템으로 인해 제한이있을 수 있지만이 함수를 호출 할 필요가없고 인수 유형이 무엇인지에 대한 요구가없는 프로토콜과 관련하여 유용합니다. 될 것입니다.

자세한 내용은 swift-evolution 메일 링리스트의 최신 게시물을 확인하십시오.


7
"swift-evolution 메일 링리스트의 최신 게시물"은 매우 명확하거나 안정적인 참조가 아닙니다. 메일 링리스트의 웹 아카이브가 없습니까?
Derek Elkins가 SE를
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.