합계 유형-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 IntDouble또는 그 반대로 캐스팅하는 것을 원하지 않습니다 . 방금 두 가지 유형을 예로 사용했습니다. 당신은 모든 대체 할 수 IntaDouble함께 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.