합계 유형-Haskell에서`(show Int)와 'show (Int | Double)'이 다른 이유 | (더블 표시)`


9

왜 이것들이 동일하지 않습니까?

show $ if someCondition then someInt else some double

과

if someCondition then show someInt else show someDouble

if ... else첫 번째 예제 의 부분을 ​​표현식으로 분리하면 익명 합계 유형으로 유형을 나타낼 수 없다는 Int | Double것을 이해합니다. langauge는 자주 사용하고 Sum 유형을 지원합니다.) Either를 기반으로 데이터를 사용해야합니다 show.

여기에 제시 한 예는 사소한 것이지만 "알겠습니다. 뭔가 보여줄 것입니다. 뭔가 someCondition가"어떤 조건이 참이면 someInt가 그렇지 않으면 someDouble을 표시합니다 "보다는" 코드 중복을 줄이려면 (여기에서 쇼는 두 번 반복되지만 긴 기능 응용 프로그램 if ... else이 될 수 있으며 고려해야 할 분기가 2 개 이상일 수 있습니다)

내 마음에 컴파일러가 합계 유형 (여기 Int | Double) 을 만드는 각 유형 을 show기능 매개 변수로 사용할 수 있는지 확인하고 유형이 올바른지 여부를 결정하는 것이 쉬워야합니다 . 더 좋은 점은 show함수 string가 매개 변수 유형에 관계없이 항상 반환 하므로 컴파일러는 가능한 모든 "분기"(모든 가능한 유형)를 가지고 다닐 필요가 없습니다.

그러한 기능이 존재하지 않는 것이 선택입니까? 아니면 내가 생각하기가 더 어려워지고 있습니까?


2
는 if ... then ... else ...의에서 동일한 유형이 있어야 then하고 else일부를. 일부 프로그래밍 언어에서는 삼항 연산자로 볼 수 있습니다.
— Willem Van Onsem 20시 01 분

1
에 동의합니다 making all conversions explicit. 내 질문에, 나는 Haskell Int이 Double또는 그 반대로 캐스팅하는 것을 원하지 않습니다 . 방금 두 가지 유형을 예로 사용했습니다. 당신은 모든 대체 할 수 Int와 a와 Double함께 b두 가지 유형이 파생 내 문제 Show. 나는 anonymous sum typesHaskell 에 없다는 것을 이해 하지만 그것이 왜 그런지, 그리고 언어를 디자인하는 데 방해가되는 이유를 알고 싶습니다.
— Mehdi Saffar

4
이러한 유형을 공용체 유형 이라고 합니다 . 합계 유형은 기본적으로 유니온 유형 의 태그 변형이며, 각 값은 내부 유형의 값을 넘어 왼쪽 / 오른쪽 태그를 포함해야합니다. Haskell의 모든 유형 수준 기능을 갖춘 유니온 유형의 유형 유추는 달성하기가 매우 어렵습니다. 만약 x :: Int | Bool우리가 컴파일해야 한다면 , 타입 삭제 기반 RTS에서 show x호출에 사용할 함수 포인터를 알 수있는 쉬운 방법은 없습니다 show. 우리는 아마도 런타임에 몇 가지 유형 수준 정보를 유지해야 할 것입니다.
— chi

1
익명 합계 유형이없는 것은 Haskell 디자이너의 디자인 결정입니다. 나는 그들이 테이블에 어떤 종류의 이익을 가져다 줄지 잘 모르겠습니다. 따라서 제 생각에는 비용 / 혜택 비율이 없기 때문에 제외됩니다. 그러나 절대적으로 원어민 디자이너 및 / 또는 현재 관리자에게 문의해야합니다. 언어 디자인과 관련된 개인적인 의견과 취향이 많기 때문에 그렇게 큰 질문을 할 것이라고 생각하지 않습니다.
— n. '대명사'm.

4
(String, Int)익명이 아닙니다. 재미있는 구문을 가진 일반 제품 유형입니다. (String | Int)완전히 다른 것입니다. 자신 (Int|Int)과 동일해야하는 Int이유와 이유 를 묻는 것으로 시작하십시오 .
— n. '대명사'm.

답변:


8

식의 모든 부분은 형식이 잘 지정되어야합니다. 유형은 if someCondition then someInt else someDouble과 같아야 exists a. Show a => a하지만 Haskell은 이러한 종류의 실존 적 수량화를 지원하지 않습니다.

업데이트 : chi가 comment에서 지적했듯이 Haskell이 합집합 / 교차 유형 (합 / 제품 유형과 동일하지 않음)을 지원했지만 불행히도 그렇지 않은 경우에도 가능합니다.


조합 / 교차로 유형과 합계 / 제품 유형의 차이점에 대해 자세히 설명해 주시겠습니까? 나는 익명 성을 제외하고는 항상 같다고 생각 했습니까?
— Mehdi Saffar

1
@MehdiSaffar 이름이 지정되지 않은 생성자가 아닌 태그가없는 것과 같은 익명입니다. 다시 말해, 당신 Int ∪ Double이을 가지고 있다면, 둘 중 하나를 가지고 있다는 것을 알 것입니다. 그러나 어떤 것을 알기 위해 패턴 일치를 할 수 없기 때문에, 두 가능성 모두에 유효한 것만 할 수 있습니다.
— Joseph Sible-Reinstate Monica

2
명확성을 위해 TypeScript에는 런타임에 사용 가능한 유형 정보가 있으므로 typeof태그가없는 것을 보완하고 어떤 유형이 사용되는지 확인할 수 있는 연산자가 있습니다. Haskell은 완전히 지워 지므로이 기능을 지원하면 이에 상응하는 기능이 없습니다.
— Joseph Sible-Reinstate Monica 20시 42 분

7

(,)Haskell 에는 가벼운 구문으로 작성된 제품 유형이 있습니다 . 간단한 구문을 가진 합 유형 (Int | String)이 좋은 아이디어 일 것입니다. 현실은 더 복잡합니다. 이유를 보자 (나는 자유를 가지고 있지만 Num중요하지 않다).

if someCondition then 42 else "helloWorld"

이것이와 같은 유형의 값을 반환해야한다면 다음은 (Int | String)무엇을 반환해야합니까?

if someCondition then 42 else 0

(Int | Int)분명히, 그러나 이것이 평범하지 않은 경우 Int우리는 큰 어려움에 처해 있습니다. 따라서 (Int | Int)plain과 동일해야합니다 Int.

이것은 합계 유형에 대한 간단한 구문 일뿐만 아니라 완전히 새로운 언어 기능이라는 것을 즉시 알 수 있습니다. 당신이 원한다면 다른 종류의 시스템. 하나 가져야합니까?

이 기능을 보자.

mysteryType x a b = if x then a else b

이제 어떤 유형 mysteryType이 있습니까? 명백하게

mysteryType :: Bool -> a -> b -> (a|b)

권리? 이제 같은 유형 a이고 b동일한 경우?

let x = mysteryType True 42 0

이것은 Int우리가 이전에 동의 한대로 분명해야합니다 . 이제는 mysteryType때로는 익명 인수 유형을 반환하지만 전달하는 인수에 따라 그렇지 않습니다. 그러한 표현과 패턴을 어떻게 일치시겠습니까? 지구상에서 무엇을 할 수 있습니까? "show"와 같은 사소한 것 (또는 다른 유형 클래스의 메소드는 인스턴스가 될 것입니다)을 제외하고는 많지 않습니다. 언어에 런타임 유형 정보를 추가하지 않는 한 typeof사용 가능하며 Haskell을 완전히 다른 언어로 만듭니다.

그래 Haskell이 TypeScript가 아닌 이유는 무엇입니까? 다른 TypeScript가 필요하지 않기 때문입니다. TypeScript를 원한다면 어디서 찾을 수 있는지 알고 있습니다.


1
@MichaWiedenmann 솔직히 "관련"이 올바른 단어인지는 모르겠습니다. 나는 그것이 어떤 식 으로든 도움이된다고 생각합니다. 예, 잠시 멈춰서 포함 시킬지 생각했습니다. 그러나 나는 때때로 틀린 것으로 알려져 있습니다.
— n. '대명사'm.

문제 없습니다, 당신의 게시물은 결정합니다.
— Micha Wiedenmann

그래서 당신의 대명사는 무엇입니까?
— dfeuer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.