하스켈 타입 시스템은 함수형 프로그래밍을 이해하는 데 방해가됩니까? [닫은]


33

다른 언어 (주로 Grovy, Python, JavaScript)로 얻은 통찰력을 적용 할 것으로 기대하면서 함수형 프로그래밍을 이해하기 위해 Haskell을 공부하고 있습니다.

나는 매우 순전히 기능적이고 국가에 대한 의존을 허용하지 않을 것이라는 인상을 받았기 때문에 Haskell을 선택합니다.

나는 매우 엄격한 유형의 시스템을 탐색하는 데 관심이 있었기 때문에 Haskell을 배우기로 선택하지 않았습니다.

제 질문은 이것입니다 : 강력한 타입의 시스템은 매우 순수한 기능적 언어의 필수 부산물입니까, 아니면 Haskell과 관련이없는 디자인 선택입니까?


6
명시 적으로 아무것도 입력하지 않으려면 명시 적으로 아무것도 입력하지 않아도됩니다. Haskell은 자체적으로 유형을 유추 할 수 있습니다. 그리고 두 개의 호환되지 않는 유형을 저장하는 단일 변수를 갖는 것과는 다릅니다.
아논.

4
@Anon 예. 그러나 목록은 동종이어야합니다. 날 믿어, 이런 종류의 일은 유형 유추로도 방해가 될 수 있습니다.
Eric Wilson

13
@ FarmBoy와 Maybe 사용의 문제점은 무엇입니까? Java는 정말로 모든 클래스에서 Maybe를 사용하도록합니다.
대안

3
이기종 목록 을 실제로 사용하려면 대수 데이터 유형을 사용할 수 있습니다.
대안

1
@mathepic이 시점에서 우리는 원래의 질문을 실제로 잃어 버렸습니다.이 질문은 완벽하게 유효한 질문이었습니다.
Eric Wilson

답변:


40

Haskell의 타입 시스템을 이해하는 것이 기능적 프로그래밍을 이해하는 데 도움이된다고 생각합니다.

순전히 함수형 프로그래밍에 관한 것은 부작용이 없을 때 모든 종류의 일을 암시 적으로 수행 할 수있게하는 것입니다. 순전히 함수형 프로그래밍은 프로그램의 구조를 훨씬 더 명확하게 만듭니다.

Haskell은 카펫 아래에 물건을 넣지 못하도록하고, 프로그램의 구조를 명시 적으로 다루도록 강요하며, 이러한 구조를 설명하는 언어 인 유형의 언어를 가르쳐줍니다. 유형, 특히 Haskell과 같이 풍부한 유형을 이해하면 모든 언어에서 더 나은 프로그래머가 될 수 있습니다.

Haskell을 강력하게 입력하지 않으면 모나드, 응용 함수 등의 개념이 프로그래밍에 적용되지 않았을 것입니다.


2
이것은 좋은 대답입니다. 제 유형은 처음에는 유형 시스템이 비정상적으로 보일 수 있지만 나중에 고급 개념을 배우기 시작할 때 해당 유형을 준수하기 때문에 수행 할 수있는 특정 작업이 있음을 알 수 있습니다 시스템 (위의 목록에 STM 및 데이터 병렬 추가). 다른 유형의 시스템에서 스타터가 아닌 것은 Haskell 시스템과 자연스럽게 맞습니다. 내 충고 : 한동안 고수하고 시간이 지남에 따라 가라 앉히십시오 ( "크램"언어가 아닙니다).
anon

2
나는 이것이 매우 오래된 대답이라는 것을 알고 있지만 실제로는 동의하지 않습니다. 몇 가지로 명시 특히 국가와 파섹과 같은 모나드와 언어, 유형 시스템에있을 수 있습니다 나는 그렇게 생각하는 스윕 TON 카펫에서 물건을. 이것은 실제로 언어 라이브러리를 배우는 나의 능력을 방해합니다.
Savanni D' Gerinel

4
@ SavanniD'Gerinel : 나는이 답변에서 "카펫 아래에 물건을 넣는 것"은 암시 적 기능을 추가하는 것을 의미하지는 않지만 (하스켈이 모나드를 통해 제어 된 방식으로 보일러 플레이트를 줄이는 데 도움이 됨) 코드를 약간 허용하는 것을 의미합니다 예상하지 못한 일을하십시오. 예 : Haskell의 순수한 기능에는 부작용이 없습니다. 기간. 다른 많은 언어에서는 함수의 문서에서 이것을 약속 할 수 있지만, 언어의 어떤 것도 코드의 어딘가에 부작용을 일으킬 수 없습니다.
Giorgio

33

가장 동적으로 형식화 된 기능 언어는 아마도 체계입니다. 하스켈의 타입 시스템은 순도를 나타내는 지표입니다. "순도를 어떻게 측정합니까?"라는 질문입니다. Haskell의 타입 시스템을 사용하면에서 불쾌한 행동을 쉽게 제거 할 수 있습니다 IO. 그러기 위해서는 정적 타입 시스템이 필요합니다.

그러나 Haskell의 타입 시스템은 함수형 프로그래밍과 관련이 없다고 가정 해 봅시다. 타입 시스템이 이러한 교육적 노력에 도움이되지 않을 것이라고 주장하는 것은 여전히 ​​허비의 높이 일 것입니다. Haskell의 타입 시스템은 풍부하고 복잡하며 C ++ 및 OCaml의 타입 시스템과 비교할 때 더욱 흥미 롭습니다.

장애물입니까? 아니요, 자산이라고 생각합니다. IO예를 들어 하스켈의 게으름을 처리하는 방법을 고려하십시오 .


8
+1 Haskell의 타입 시스템은 익숙해지면 친구가 될 수 있습니다.
Larry Coleman

"그렇게하려면 정적 타입 시스템이 필요하다". 정말?
Jon Harrop 2019

1
"C ++ 및 OCaml의 유형 시스템과 비교할 때 더욱 흥미 롭습니다." OCaml의 최고급 고차 모듈과 구조적으로 형식화 된 유추 된 객체 시스템 및 다형성 변형을 연구 했습니까?
Jon Harrop 2019

2
@JonHarrop 또는 효과 시스템 또는 순도 측정 / 평가 방법. 그렇기 때문에 그것들을 비교하는 것이 흥미로운 이유입니다. 언어마다 다른 선택이 있습니다.
로건 카파도

20

Clojure는 동적으로 유형이 지정되어 있으며 Haskell만큼이나 순수하기 때문에 Haskell의 유형 시스템이 절대적인 요구 사항보다 디자인 선택에 더 가깝다는 좋은 주장이 있습니다. 둘 다 확실히 장점이 있으므로 하스켈의 강성을 정말로 좋아하지 않는다면 Clojure를 고려할 수도 있습니다 (그러나 아래 참조).

처음 Haskell을 사용하기 시작했을 때, 나는 타입 시스템이 성가신 것으로 간주하고 타입 유추 때문에 허용했습니다. 나는 컴파일러가 나를 허용하더라도 (예를 들어 실수로 concatMap 대신 map을 사용하여) 어쨌든 작동하지 않은 것들에 대해 컴파일러가 불평하는 많은 유형 오류를 발견했습니다. 그런 다음 형식 검사를 통과 한 프로그램이 일반적으로 정확하거나 적어도 수정에 가깝다는 것을 알았습니다. 함수 유형을 변경하고 컴파일러에게 변경해야 할 사항을 알려 주어 리팩토링을 수행 한 게으른 단계조차있었습니다. 마지막으로, Haskell의 타입 시스템은 실제로 매우 표현력이 뛰어나서 타입을 중심으로 프로그램을 설계하기 시작했습니다. 이것이 하스켈의 성배입니다.


주목해야 할 또 다른 사항 : Scheme과 Haskell을 동시에 사용하여 기능 프로그래밍을 배웠습니다. 나는 Scheme 의 s 및 s 보다 Haskell의 패턴 일치를 사용하여 재귀를 이해하는 것이 훨씬 쉽다는 것을 알았습니다. ifcond
Tikhon Jelvis

@Larry Coleman : 유형 시스템에 대한 나의 경험을 정확하게 설명해 주신 +1 : 먼저 C ++, Ocaml, 그리고 이제는 자신의 언어 Felix. 예, 여전히 컴파일러 오류를 추적하여 리팩터링합니다.
Yttrill

8

Haskell의 타입 시스템은 순수한 코드에서 효과를 분리하는 기능의 핵심입니다. 다른 방법으로 효과를 분리하거나 효과를 완전히 제거하지 않는 한, 강력한 정적 유형 시스템은 순수한 기능 프로그래밍에 필요합니다.

Haskell은 강력한 정적 유형 시스템을 가진 언어의 좋은 예입니다. 특히 컴퓨터 과학 및 프로그래밍 언어 디자인에 대한 광범위하고 둥근 교육을 원한다면 Haskell은 배우는 언어 중 하나로서 탁월한 선택이 될 것입니다.

타입 시스템은 큰 장애물이되어서는 안됩니다. 동적 언어를 사용하는 경우에도 프로그램을 작성하는 사람들은 Haskell의 유형 시스템을 사용하여 인코딩 할 수있는 입력 규칙을 따릅니다. Haskell은 C ++ 및 Java와 같은 언어와 비교할 때 자세한 내용을 완화하는 형식 유추 기능도 제공합니다. 오류 메시지가 표시되면 컴파일러는 컴파일 타임에 동적 유형의 언어가 런타임에 무엇을 알려주는지 알려줍니다.

동적 유형 시스템의 반대는 강력한 유형 시스템이 아니라 정적 유형 시스템입니다. 강력한 유형 시스템은 약한 유형 시스템의 반대입니다.


1
예를 들어 C는 정적이지만 약한 유형입니다. 유형이 있지만 유형 시스템을 완전히 전복하고 기본 기계 별 표현 등을 사용하는 것은 쉽습니다. OTOH는 유형 체계를 전복시키는 묵시적 캐스트가 거의 없으며 몇 가지 방법이있는 경우 매우 강력하게 유형이 지정됩니다.
Steve314

4

바보 같은 실수를 할 때 바로 알려줍니다. 도움이됩니다. 나는 지난 달 라켓 (Scheme)에서 일해 왔으며, 해석되지 않은 s-exp를 통과하여 해석기의 일부 기능에 대한 구문 분석 된 ast를 예상 한 경우가 많았습니다. 중형 테스트 스위트. 정적 인 타이핑이 있었다면 바로 관심을 끌었을 것입니다.

물론 타입 오류가 로직 오류를 잡을 수는 없지만 실수를 일으킬 수있는 방법의 수는 크게 줄어 듭니다.

또한 유형 유추를 통해 원하는 경우 유형 시스템을 무시할 수 있습니다. 여전히 존재하지만 사용자가 직접 입력 할 필요는 없습니다. 함수의 유형을 이해하는 것이 여전히 도움이되지만 올바른 코드는 정상적으로 작동합니다.

Haskell의 순도는 유형 시스템으로 인코딩됩니다. IO 모나드는 불순 코드가 순수한 기능으로 누출되는 것을 막는 타입 레벨 구성이므로 타입 시스템에 의해 순도가 보장됩니다.


8
하스켈 타입 시스템을 무시할 수 있다고 생각한다면 하스켈을 많이 코딩하지 않았다고 생각합니다.
Eric Wilson

함수를 입력하고 GHCi에로드 한 다음 무시하십시오. 그러나 때때로 integral 또는 다른 기능에서 일부를 뿌려야합니다.
Theo Belaire

1
Tyr은 형식 유추에도 불구하고 Haskell 함수 사용 및 코딩의 90 %가 망쳐 놓은 것을 서로 맞물리게하므로 형식 시스템과 비전형 형식 검사 오류 메시지를 이해해야합니다. ": t"조차 마법 같은 솔루션이 아니며 프로그램 컴파일 방법을 이해하는 첫 번째 단계 일뿐입니다.
Andres F.

글쎄요, 일부는 지저분합니다. 나는 전주곡의 숫자를 정리하고 고칠 수 있다고 생각합니다. 그것이 서 있기 때문에 끔찍한 혼란이기 때문입니다. 그러나 대부분의 주요 기능적 측면은 매우 깨끗합니다. 지도, 필터, foldr / l 및 기타 재미있는 기능적 기능은 매우 훌륭하게 작동합니다.
테오 벨레 르

2

"기능적"언어라는 것은 언어에서 기능이 일급 객체라는 것을 의미합니다.

"순수한"언어는 함수가 수학 함수 (절차가 아니라)라는 것을 의미합니다. 동일한 입력이 주어지면 항상 동일한 출력을 생성합니다.

"순수한 기능 언어"는 위의 두 가지가 모두 포함되는 언어입니다. 나는 "pure- 인식하지 오전 LY 기능적인 언어".

강력한 유형의 시스템은 순수하면서도 실용적인 언어를 사용하는 깔끔한 방법입니다. 형식은 정확성을 더욱 보장하는 형태를 제외하고 컴파일러가 최적화를 파악하는 데 도움이됩니다. (그러나 이것이 유일한 방법은 아닙니다. 클로저는 순수하지만 하스켈만큼 강력한 유형 시스템을 가지고 있지 않습니다.)

타입 시스템이 당신을 귀찮게한다면, Scheme과 같은보다 역동적 인 언어를 시도하거나 Haskell의 타입 추론 시스템을 사용하는 것이 좋습니다.


0

예, 타입 시스템은 놀라운 자산입니다. 모나드의 작동 방식이나 일부 콤비 네이터가 타입 시스템없이 작동하는 방식을 설명하기조차 매우 어렵습니다. Haskell에 대한 몇 개의 튜토리얼이 먼저 REPL에서 : t를 사용하여 해당 함수의 유형을 고려하도록 요청하는지 고려하십시오. 동적으로 입력 된 언어로는 사용할 수 없습니다. 물론 타입 시스템의 모든 복잡성은 여전히 ​​존재합니다. 모나드는 여전히 모나드입니다. 그러나 언어는 문제의 손을 씻고 아무런 도움도 제공하지 않기로 결정했습니다. 당신은 당신 자신의 친구 야. 동적으로 유형이 지정된 언어를 사용하지 않습니다. 나는 그들을 사랑합니다. 구성표는 탁월한 전동 공구입니다. 그러나 우리는 다이나믹 언어로 된 모나드와 같은 것에 대해 이야기 할 때 종종 표기법을 발명한다는 것을 알 수 있습니다절차 유형을 설명합니다. 함수형 프로그래머는 어떤 식 으로든 다른 방식으로 싸울 것입니다. Haskell의 유형 검사기는 그 방법을 배울 수있는 훌륭한 도구를 제공합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.