Haskell에서 Enum의 서브 클래스가 아닌 이유


9

바운드 인스턴스는 Enum을 제대로 구현 한 것처럼 보입니다. 누군가가 병적 인 것이 아닌 것을 생각해 내면 왜 이것이 그렇지 않은지 이해할 것입니다.

:i두 가지 유형 클래스 에서 수행 하면 현재 표준 라이브러리에있는 유일한 예외는 바운드이지만 Enums는 아닙니다. 그러나 모든 마지막 튜플은 단순히 마지막 요소를 증가시킨 다음 maxBound에 도달하면 감싸는 방식으로 깔끔하게 열거 할 수 있어야합니다.

이 변경에는 아마도 Enum 값을 통과하는 안전 / 루핑 방법을 위해 경계에 추가 predBnextB/ 또는 이와 유사한 것이 포함 됩니다. 이 경우에 toEnum 0 :: (...)동일 할 것이다(toEnum 0, toEnum 0, ...) :: (...)


3
실제로 정식으로 대답 할 수는 없지만 0과 1 사이의 모든 실수의 범위를 고려하십시오. 명확한 하한과 상한은 있지만 셀 수없이 무한한 멤버가 있습니다.
Doval

@Doval 그것은 공정한 포인트입니다. 그러나 같은 일반 (uncountably 무한 멤버)의 모든 실수,하지만에 대해 말할 수있다 Double/ Float모든 유사한 유형 구현할 Enum그들은 단지 확인 어쨌든 succ = (+ 1)하고 fromEnum = truncate. Haskell의 방법은 실제로는 다른 관점에서 실용적 관점에서 의미가 있으며 [0, 0.5 ..]와 유사하게 작동하지 않으므로, Haskell은 Enums와 관련하여 셀 수에 대해 걱정하지 않는 것 같습니다.
세미콜론

1
나는 알고하지 않았다 succ입니다 (+1). 그 때문에, 이상하다 Double하고 Float무한한 정밀도를 가지고 있고, 따라서 없습니다 입니다 열거 - succ1로 정의했습니다 수 ULP .
Doval

2
@Doval 그 이유는 Haskell 핵심 팀이 [1 ..]이 Doubles와 Ints와 같은 의미를 갖기를 원했기 때문이라고 생각합니다.
세미콜론

@semicolon double 및 float는 실수가 아니므로 (예 : 정밀도를 잃지 않고 PI를 double에 저장할 수 없음) 열거 할 수 있습니다
jk.

답변:


8

내가 좋아하는 한 가지 실제적인 예는 프로그래밍 언어의 세계에서 온 것입니다. OO 시스템의 유형 집합은 경계가 있고 별개이지만 열거 할 수 없으며 부분적으로 정렬되었지만 완전히 정렬되지 않았습니다.

문제의 부분 순서는 하위 유형 관계 <:입니다. 그러면 상한이 최상위 유형 (C # 호출 object및 스칼라 호출 Any)이되고 하한이 최하위 유형이됩니다 (Scala 's Nothing; C # / Java는 이에 해당하지 않음).

그러나 형식 시스템의 모든 형식을 열거 할 수있는 방법이 없으므로를 쓸 수 없습니다 instance Enum Type. 명확해야합니다. 사용자는 자신의 유형을 작성할 수 있으므로 미리 어떤 것을 알 수있는 방법이 없습니다. 주어진 프로그램에서 모든 유형을 열거 할 수 있지만 전체 시스템에서는 그렇지 않습니다.

마찬가지로 (하위 유형의 특정 합리적인 정의에 따라) <:반사, 전이 및 비대칭이지만 총체는 아닙니다 . 와 관련이없는 유형의 쌍이 있습니다 <:. ( Cat및 의 하위 유형이지만 둘 Dog다의 하위 유형이 Animal아닙니다.)


간단한 OO 언어 용 컴파일러를 작성한다고 가정하십시오. 시스템의 유형 표현은 다음과 같습니다.

data Type = Bottom | Class { name :: String, parent :: Type } | Top

그리고 서브 타이핑 관계의 정의 :

(<:) :: Type -> Type -> Bool
Bottom <: _ = True
Class _ _ <: Bottom = False
Class n t <: s@(Class m _)
    | n == m = True  -- you can't have different classes with the same name in this hypothetical language
    | otherwise = t <: s  -- try to find s in the parents of this class
Class _ _ <: Top = True
Top <: Top = True
Top <: _ = False

이것은 또한 우리에게 수퍼 타이핑 관계를 제공합니다.

(>:) :: Type -> Type -> Bool
t >: s = s <: t

또한 두 가지 유형 중 최소 상한을 찾을 수 있습니다.

lub :: Type -> Type -> Type
lub Bottom s = s
lub t Bottom = t
lub t@(Class _ p) s@(Class _ q) =
    | t >: s = t
    | t <: s = s
    | p >: s = p
    | t <: q = q
    | otherwise = lub p q
lub Top _ = Top
lub _ Top = Top

연습 : 아래 및 아래의 두 가지 방법으로 경계가있는 완전한 자세Type형성 함을 보여줍니다 .<:>:


정말 고마워! 그것은 내 질문에 완전히 대답하고 Ord에 대한 나의 후속 질문에도 대답합니다. Eq도 비슷한 문제가 있습니까? 동일하지 않은 유형에 maxBound 또는 minBound가있을 수 있습니다. 이 경우 Cat == Dog는 다른 클래스이므로 false를 반환해야합니까, 아니면 트리 위치로 인해 위 또는 아래에 위치하지 않기 때문에 결정할 수 없습니까?
세미콜론

순서는 평등을 의미합니다 x == y = x <= y && y <= x. 내가 Poset수업 을 디자인 했다면 class Eq a => Poset a. 빠른 Google은 다른 사람들이 동일한 아이디어를 가지고 있음을 확인합니다 .
Benjamin Hodgson

죄송하지만 내 질문은 모호했습니다. 내가 의미하는 바는 Ord를 암시하지 않더라도 Bounded가 Eq를 암시했는지 여부였습니다.
세미콜론

@semicolon 두 클래스 사이에는 아무런 관계가 없습니다. 고려 data Bound a = Min | Val a | Max유형을 증대하는 a+∞-∞요소. 건설 Bound a을 통해 항상 실례가 될 수 Bounded있지만 기본 유형 a이 다음과 같은 경우에만 동일합니다.
Benjamin Hodgson

알았어. 나는 하나의 예를 취할 기능과 형태의 반환 값이 될 수도 있겠죠 Double, const (1/0)이다 maxBoundconst (negate 1/0)이다 minBound그러나 \x -> 1 - x\x -> x - 1비교할 수 있습니다.
세미콜론

4

작업이 독립적이기 때문에 하위 클래스 관계와 함께 묶는 것은 실제로 아무것도 사지 않습니다. Bounded아마도 Doublesmax와 min 사이에 제약 이있는 커스텀 타입을 만들고 싶었지만 어떤 Enum작업 도 필요로하지 않았다고 가정 해 봅시다 . 경우 Bounded서브 클래스했다, 당신은 모든 구현해야 할 것이다 Enum, 어쨌든 함수를 그냥 컴파일 얻을.

에 대한 합리적인 구현 Enum또는 다른 유형의 클래스가 있는지는 중요하지 않습니다 . 실제로 필요하지 않은 경우 구현하지 않아도됩니다.

말 명암이, Ord하고 Eq. 여기에서 Ord작업은 작업에 따라 Eq다르므로 중복을 피하고 일관성을 유지하기 위해 서브 클래스를 요구하는 것이 좋습니다.


1
이 경우 정의의 일부입니다. 모든 모나드는 정의에 따라 응용 프로그램 및 펑터이기도하므로 모나드 "계약"을 수행 할 수는 없습니다. 나는 그것이 기본적인 관계인지 부과 된 정의인지 알기에는 수학에 익숙하지 않지만, 어느 쪽이든, 우리는 지금 그것을 고수하고 있습니다.
Karl Bielefeldt

6
@semicolon에 대한 문서Bounded 는 "정렬로 정렬되지 않은 유형에도 상한과 하한이있을 수 있으므로 Ord는 Bounded의 수퍼 클래스가 아닙니다."라고 말합니다.
Benjamin Hodgson 2016 년

1
@ BenjaminHodgson 부분적으로 정렬 된 유형조차 생각하지 않았습니다. 비 병리학 적 예와 문서 인용에 +1.
Doval

1
@semicolon 컴퓨터 세계에서 부분적으로 주문하는 예는 OO 언어로 하위 유형을 정의 할 수 있습니다. 쓰기 <:위한 것이 의 하위 유형이다 , ∀ T S. T <: S ∨ S <: T보유하지 않습니다 (예를 들어, int !<: bool ∧ bool !<: int). 컴파일러를 작성하는 경우이 문제가 발생할 수 있습니다.
Benjamin Hodgson

1
@BenjaminHodgson 아 좋아. 예를 들어 A가 B와 C의 슈퍼 클래스이고 D가 B와 C의 서브 클래스 인 경우 B와 C는 비교할 수 없지만 A와 D는 최대 / 분입니까?
세미콜론
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.