Haskell에 대한 소란은 무엇입니까? [닫은]


109

나는 그들 사이에있을 때 Haskell에 대해 계속 이야기하는 몇몇 프로그래머를 알고 있으며, 여기에서는 모두가 그 언어를 좋아하는 것 같습니다. Haskell에 능숙하다는 것은 천재 프로그래머의 특징 인 것 같습니다.

누군가가 왜 그렇게 우아하고 우수한지 보여주는 몇 가지 Haskell 예제를 줄 수 있습니까?

답변:


134

그것이 저에게 제시된 방식, 그리고 지금 한 달 동안 Haskell에서 학습 한 후 사실이라고 생각하는 것은 함수형 프로그래밍이 흥미로운 방식으로 당신의 두뇌를 뒤틀린다는 사실입니다. 익숙한 문제에 대해 여러 가지 방식으로 생각하게합니다. : 루프 대신 맵과 접기 및 필터 등으로 생각하십시오. 일반적으로 문제에 대해 둘 이상의 관점이있는 경우이 문제에 대해 추론하고 필요에 따라 관점을 전환 할 수 있습니다.

Haskell의 또 다른 멋진 점은 타입 시스템입니다. 엄격하게 유형이 지정되어 있지만 유형 추론 엔진은 바보 같은 유형 관련 실수를했을 때 마술처럼 알려주는 Python 프로그램처럼 느껴집니다. 이와 관련하여 Haskell의 오류 메시지는 다소 부족하지만 언어에 익숙해지면 스스로에게 말할 것입니다 : 이것이 타이핑이되어야하는 것입니다!


47
Haskell의 오류 메시지가 부족하지 않고 ghc가 있다는 점에 유의해야합니다. Haskell 표준은 오류 메시지가 수행되는 방법을 지정하지 않습니다.
PyRulez

저 같은 사람들에게 GHC는 Glasgow Haskell Compiler를 의미합니다. en.wikipedia.org/wiki/Glasgow_Haskell_Compiler
로렘 입숨

137

이것은 내가 Haskell을 배우도록 설득 예입니다.

-- program to copy a file --
import System.Environment

main = do
         --read command-line arguments
         [file1, file2] <- getArgs

         --copy file contents
         str <- readFile file1
         writeFile file2 str

좋습니다. 짧고 읽기 쉬운 프로그램입니다. 그런 의미에서 C 프로그램보다 낫습니다. 그러나 이것이 매우 유사한 구조를 가진 파이썬 프로그램과 어떻게 다른가요?

대답은 게으른 평가입니다. 대부분의 언어 (일부 기능적 언어 포함)에서 위와 같이 구조화 된 프로그램은 전체 파일이 메모리에로드 된 다음 새 이름으로 다시 작성됩니다.

Haskell은 "게으른"사람입니다. 필요할 때까지 계산하지 않으며, 더 이상 필요 하지 않은 것을 계산 하지 않습니다 . 예를 들어, 만약 당신이 writeFile줄 을 제거한다면 , Haskell은 처음에 파일에서 아무것도 읽지 않을 것입니다.

그대로 Haskell은가에 writeFile의존 한다는 것을 인식 readFile하고이 데이터 경로를 최적화 할 수 있습니다.

결과는 컴파일러에 따라 다르지만 위 프로그램을 실행할 때 일반적으로 발생하는 일은 다음과 같습니다. 프로그램은 첫 번째 파일의 블록 (예 : 8KB)을 읽은 다음 두 번째 파일에 쓴 다음 첫 번째 파일에서 다른 블록을 읽습니다. 두 번째 파일에 씁니다. (실행 해보세요 strace!)

... 이것은 파일 복사의 효율적인 C 구현이하는 것과 매우 유사합니다.

따라서 Haskell을 사용하면 많은 성능을 저하시키지 않고 간결하고 읽기 쉬운 프로그램을 작성할 수 있습니다.

내가 추가해야 할 또 다른 것은 Haskell이 단순히 버그가있는 프로그램을 작성하는 것을 어렵게 만든다는 것입니다. 놀라운 유형 시스템, 부작용 부족, 물론 Haskell 코드의 간결함은 최소한 세 가지 이유로 버그를 줄입니다.

  1. 더 나은 프로그램 디자인. 복잡성이 감소하면 논리 오류가 줄어 듭니다.

  2. 간결한 코드. 버그가있을 줄이 적습니다.

  3. 컴파일 오류. 많은 버그 는 유효한 Haskell이 아닙니다 .

Haskell이 모든 사람을위한 것은 아닙니다. 그러나 모두가 그것을 시도해야합니다.


8KB 상수 (또는 그것이 무엇이든)를 정확히 어떻게 변경 하시겠습니까? 나는 하스켈 특히 프리 페치하지 않고, 그렇지 않으면 C 버전보다 속도가 느린 것입니다 구현 ... 셨을 텐데요 때문에
user541686

1
@Mehrdad를 사용하여 버퍼 크기를 변경할 수 있습니다 hSetBuffering handle (BlockBuffering (Just bufferSize)).
David

3
이 답변에 116 개의 찬성표가 있지만 거기에있는 내용이 잘못되었다는 것이 놀랍습니다. 이 프로그램 Data.Bytestring.Lazy.readFile 하스켈이 게으른 (엄격하지 않은) 언어 인 하스켈과 관련이없는 게으른 바이트 스트링 (로 할 수있는 ) 을 사용하지 않는 한 전체 파일 읽습니다 . 모나드는 시퀀싱입니다 . 이것은 대략 "결과를 꺼내면 모든 부작용이 수행됩니다"를 의미합니다. "lazy Bytestring"마법에 관해서는 위험합니다. 대부분의 다른 언어에서 비슷하거나 더 간단한 구문으로 할 수 있습니다.
Jo So

14
지루한 오래된 표준 readFile도 같은 방식으로 게으른 IO를 Data.ByteString.Lazy.readFile수행합니다. 따라서 대답은 틀린 것이 아니며 단순히 컴파일러 최적화가 아닙니다. 실제로 이것은 Haskell 사양의 일부입니다 . "이 readFile함수는 파일을 읽고 파일의 내용을 문자열로 반환합니다. 파일은에서와 같이 요청시 느리게 읽 힙니다 getContents."
Daniel Wagner

1
다른 답변은 Haskell에 대해 더 특별한 것을 지적한다고 생각합니다. 많은 언어 / 환경에 스트림이 있으며 Node :에서 유사한 작업을 수행 할 수 있습니다 const fs = require('fs'); const [file1, file2] = process.argv.slice(2); fs.createReadStream(file1).pipe(fs.createWriteStream(file2)). 배쉬도 비슷한 일이 있습니다cat $1 > $2
최대 Heiber

64

당신은 잘못된 질문을하고 있습니다.

하스켈은 몇 가지 멋진 예제에서 살펴 가서가는 언어가 아닙니다 "아하, 내가 지금 참조 입니다 그것은 좋은 만드는 것!"

마치, 우리는 다른 모든 프로그래밍 언어를 가지고 있고, 그것들은 모두 다소 비슷합니다. 그리고 완전히 다르고 엉뚱한 Haskell이 있습니다. 일단 당신이 괴팍함에 익숙해지면 완전히 굉장합니다. 그러나 문제는 그 괴팍함에 적응하는 데 꽤 오랜 시간이 걸린다는 것입니다. Haskell을 다른 거의 모든 준 주류 언어와 차별화시키는 요소 :

  • 게으른 평가
  • 부작용 없음 (모든 것이 순수하고 IO / etc는 모나드를 통해 발생 함)
  • 놀랍도록 표현력이 풍부한 정적 유형 시스템

뿐만 아니라 많은 주류 언어와는 다른 (하지만 일부에서 공유하는) 몇 가지 다른 측면 :

  • 기능의
  • 중요한 공백
  • 유추 된 유형

다른 포스터가 대답했듯이 이러한 모든 기능의 조합은 완전히 다른 방식으로 프로그래밍에 대해 생각한다는 것을 의미합니다. 그래서 이것을 Joe-mainstream-programmer에게 적절하게 전달하는 예 (또는 일련의 예)를 생각해 내기는 어렵습니다. 그것은 경험적인 것입니다. (비유하자면 1970 년 중국 여행 사진을 보여 드릴 수는 있지만 사진을보고 나면 그 기간 동안 그곳에서 살았던 것이 어떤 것인지 알 수 없습니다. 마찬가지로 Haskell을 보여 드릴 수 있습니다. 'quicksort'이지만 Haskeller라는 것이 무엇을 의미하는지 여전히 알 수 없습니다.)


17
나는 당신의 첫 문장에 동의하지 않습니다. 처음에는 Haskell 코드의 몇 가지 예에 정말 감명을 받았으며 실제로 배울 가치가있는 것은이 기사였습니다. cs.dartmouth.edu/~doug/powser.html 하지만 물론 이것은 수학자 / 물리학 자에게는 흥미 롭습니다. 실제 상황을 조사하는 프로그래머는이 예제가 우스꽝 스러울 것입니다.
Rafael S. Calsaverini 2009

2
@Rafael : "실제 세계를 들여다 보는 프로그래머는 무엇에 감명을받을 까"라는 질문을 던집니다.
JD

좋은 질문! 저는 "실제"프로그래머가 아니기 때문에 그들이 무엇을 좋아하는지 모르겠습니다. 하하하 ... 나는 물리학 자와 수학자들이 좋아하는 것을 압니다. : P
Rafael S. Calsaverini

27

Haskell을 진정으로 차별화하는 것은 함수형 프로그래밍을 적용하기 위해 설계에서들이는 노력입니다. 거의 모든 언어로 기능적인 스타일로 프로그래밍 할 수 있지만, 처음에는 포기하기가 너무 쉽습니다. Haskell은 함수형 프로그래밍을 포기하는 것을 허용하지 않으므로 논리적 인 결론에 도달해야합니다. 이는 추론하기 더 쉬운 최종 프로그램이며 가장 까다로운 유형의 버그 전체를 피해야합니다.

실제 사용을위한 프로그램을 작성할 때 Haskell이 실용적인 방식이 부족하다는 것을 알 수 있지만, 처음부터 Haskell을 아는 것이 최종 솔루션이 더 좋습니다. 나는 아직 거기에 있지 않지만 지금까지 Haskell을 배우는 것은 Lisp가 대학에 있었다고 말하는 것보다 훨씬 더 깨달았습니다.


1
음, 항상 단지 및 / 또는 ST 모나드를 사용할 수있는 가능성 거기에 항상 unsafePerformIO바로 세계 화상을보고 싶은 사람들을 위해이)
사라

22

소란의 일부는 순도와 정적 타이핑이 공격적인 최적화와 결합 된 병렬성을 가능하게한다는 것입니다. 병렬 언어는 이제 멀티 코어가 약간 파괴적이어서 뜨겁습니다.

Haskell은 빠른 네이티브 코드 컴파일러와 함께 거의 모든 범용 언어보다 더 많은 병렬 처리 옵션을 제공합니다. 병렬 스타일에 대한 이러한 종류의 지원에는 경쟁이 없습니다.

따라서 멀티 코어 작업에 관심이 있다면 Haskell이 할 말이 있습니다. 시작하기 좋은 곳 은 Haskell의 병렬 및 동시 프로그래밍에 대한 Simon Peyton Jones의 자습서입니다 .


"빠른 네이티브 코드 컴파일러와 함께"?
JD

나는 dons가 GHCI를 언급한다고 믿습니다.
그레고리 Higley

3
@Jon : shootout.alioth.debian.org/u32/… 예를 들어 Haskell은 총격전에서 꽤 잘합니다.
Peaker

4
@Jon : 총격전 코드는 매우 오래되었고 GHC가 최적화 컴파일러가 아니었던 먼 과거에서 왔습니다. 그럼에도 불구하고 Haskell 코드 필요한 경우 성능을 내기 위해 저수준으로 이동할 있음을 증명 합니다. 총격전의 최신 솔루션은 더 관용적이고 여전히 빠릅니다.
Peaker

1
@GregoryHigley GHCI와 GHC에는 차이가 있습니다.
제레미 목록


18

저는 작년에 Haskell을 배우고 그 안에 상당히 크고 복잡한 프로젝트를 작성하는 데 보냈습니다. (이 프로젝트는 자동화 된 옵션 거래 시스템이며 거래 알고리즘에서 저수준, 고속 시장 데이터 피드의 구문 분석 및 처리에 이르기까지 모든 것이 Haskell에서 수행됩니다.) 훨씬 더 간결하고 이해하기 쉽습니다. 적절한 배경)은 Java 버전보다 매우 강력합니다.

아마도 저에게 가장 큰 승리는 모노 이드, 모나드 등과 같은 것을 통해 제어 흐름을 모듈화하는 능력이었습니다. 아주 간단한 예는 Ordering monoid입니다. 다음과 같은 표현에서

c1 `mappend` c2 `mappend` c3

어디 c1그래서 반환에 LT, EQ또는 GT, c1반환 EQ원인을 식을 평가, 계속 c2; c2반환 되는 경우 LT또는 GT그것은 전체의 값이며 c3평가되지 않습니다. 이런 종류의 것은 모나 딕 메시지 생성기 및 구문 분석기와 같은 것에서 상당히 더 정교하고 복잡해집니다. 여기서는 여러 유형의 상태를 처리하거나, 다양한 중단 조건을 가지고 있거나, 중단이 실제로 의미하는지 여부를 특정 호출에 대해 결정할 수 있기를 원할 수 있습니다. "추가 처리 안 함"또는 "마지막에 오류를 반환하지만 추가 오류 메시지 수집을 위해 계속 처리"를 의미합니다.

이것은 모두 배우는 데 약간의 시간과 노력이 필요하므로 이러한 기술을 아직 모르는 사람들을 위해 설득력있는 주장을하기가 어려울 수 있습니다. 모나드모든 것 튜토리얼이 이것의 한 측면에 대한 꽤 인상적인 시연을 제공 한다고 생각 하지만, 이미 자료에 익숙하지 않은 사람이 이미 첫 번째 또는 심지어 세 번째,주의 깊게 읽었을 때 "그것을 얻을"것이라고는 기대하지 않습니다.

어쨌든 Haskell에는 다른 좋은 것들이 많이 있지만, 이것은 내가 자주 언급하지 않는 주요한 것입니다. 아마도 그것은 다소 복잡하기 때문일 것입니다.


2
매우 흥미로운! 총 몇 줄의 Haskell 코드가 자동 거래 시스템에 들어갔습니까? 내결함성을 어떻게 처리했으며 어떤 종류의 성능 결과를 얻었습니까? 나는 최근에 Haskell이 저 지연 프로그래밍에 좋은 잠재력을 가지고 있다고 생각하고 있습니다 ...
JD

12

흥미로운 예는 http://en.literateprograms.org/Quicksort_(Haskell) 에서 볼 수 있습니다.

흥미로운 것은 다양한 언어로 구현 된 것을 보는 것입니다.

Haskell을 다른 기능적 언어와 함께 흥미롭게 만드는 것은 프로그래밍 방법에 대해 다르게 생각해야한다는 사실입니다. 예를 들어 일반적으로 for 또는 while 루프를 사용하지 않지만 재귀를 사용합니다.

위에서 언급했듯이 Haskell 및 기타 기능 언어는 병렬 처리 및 다중 코어에서 작동하는 응용 프로그램 작성에 탁월합니다.


2
재귀는 폭탄입니다. 그것과 패턴 매칭.
Ellery Newcomer

1
for 및 while 루프를 제거하는 것은 기능적 언어로 작성할 때 가장 어려운 부분입니다. :)
James Black

4
루프 대신 재귀로 생각하는 법을 배우는 것도 나에게 가장 어려운 부분이었습니다. 마침내 가라 앉았을 때, 그것은 내가 지금까지 가진 가장 큰 프로그래밍 깨달음 중 하나였습니다.
Chris Connett

8
작업중인 Haskell 프로그래머가 원시 재귀를 거의 사용하지 않는다는 점을 제외하고는; 주로지도 및 폴더와 같은 라이브러리 기능을 사용합니다.
Paul Johnson

18
Hoare의 원래 퀵 정렬 알고리즘이이 비효율적 인 목록 기반 형식으로 엉망이되어 쓸데없이 비효율적 인 구현이 Haskell에서 "우아하게"작성 될 수 있다는 것이 더 흥미 롭습니다. Haskell에서 실제 (in-place) 퀵소트를 작성하려고한다면, 그것이 지옥처럼 추악하다는 것을 알게 될 것입니다. Haskell에서 경쟁력있는 제네릭 퀵소트를 작성하려고한다면 GHC 가비지 수집기의 오랜 버그로 인해 실제로 불가능하다는 것을 알게 될 것입니다. 퀵소트를 Haskell 거지의 믿음, IMHO의 좋은 예라고 환영합니다.
JD

8

예를 들어 드릴 수 없었습니다. 저는 OCaml 녀석입니다.하지만 제가 여러분과 같은 상황에 처하면 호기심이 붙을뿐입니다. 컴파일러 / 통역사를 다운로드하여 시도해보아야합니다. 주어진 기능적 언어의 강점과 약점에 대해 훨씬 더 많이 배울 것입니다.


1
컴파일러의 소스 코드를 읽는 것을 잊지 마십시오. 그것은 또한 당신에게 많은 귀중한 정보를 줄 것입니다.
JD

7

알고리즘이나 수학적 문제를 다룰 때 내가 매우 멋지다고 생각하는 것은 Haskell의 고유 한 계산에 대한 게으른 평가인데, 이는 엄격한 기능적 특성으로 인해 가능합니다.

예를 들어 모든 소수를 계산하려면 다음을 사용할 수 있습니다.

primes = sieve [2..]
    where sieve (p:xs) = p : sieve [x | x<-xs, x `mod` p /= 0]

결과는 실제로 무한 목록입니다. 그러나 Haskell은 오른쪽에서 왼쪽으로 평가하므로 전체 목록이 필요한 작업을 수행하지 않는 한 다음과 같이 프로그램이 무한대에 갇히지 않고 계속 사용할 수 있습니다.

foo = sum $ takeWhile (<100) primes

이것은 100보다 작은 모든 소수를 합산합니다. 이것은 여러 가지 이유로 좋습니다. 우선, 모든 소수를 생성하는 하나의 소수 함수 만 작성하면됩니다. 그러면 소수로 작업 할 준비가 거의되었습니다. 객체 지향 프로그래밍 언어에서는 반환하기 전에 몇 개의 소수를 계산해야하는지 함수에 알려주거나 객체로 무한 목록 동작을 에뮬레이트하는 방법이 필요합니다. 또 다른 한 가지는 일반적으로 계산하려는 것을 표현하는 코드를 작성하는 것이며, 평가할 순서가 아니라 컴파일러가 대신 수행한다는 것입니다.

이것은 무한 목록에 유용 할뿐만 아니라 실제로 필요 이상으로 평가할 필요가 없을 때 항상 알지 못하는 사이에 사용됩니다.


2
이것은 전적으로 사실이 아닙니다. C # (객체 지향 언어)의 수익 반환 동작을 사용하면 요청시 평가되는 무한 목록을 선언 할 수도 있습니다.
Jeff Yates

2
좋은 지적. 당신은 정확하고 다른 언어로 할 수있는 것과 할 수없는 것을 그렇게 단호하게 말하는 것을 피해야합니다. 내 예제는 결함이 있다고 생각하지만 여전히 Haskell의 게으른 평가 방식에서 무언가를 얻는다고 생각합니다. 기본적으로 프로그래머의 노력없이 실제로 존재합니다. 그리고 이것은 기능적 특성과 부작용이 없기 때문이라고 생각합니다.
waxwing 2009-04-22

8
"sieve"가 Eratosthenes의 Sieve 가 아닌 이유를 읽으 실 수 있습니다 . lambda-the-ultimate.org/node/3127
Chris Conway

@Chris : 고마워요, 정말 흥미로운 기사였습니다! 위의 소수 함수는 고통스럽게 느리기 때문에 내 자신의 계산에 사용했던 함수가 아닙니다. 그럼에도 불구하고이 기사는 mod에 대한 모든 숫자를 확인하는 것이 실제로는 다른 알고리즘이라는 좋은 점을 제시합니다.
waxwing

6

나는 몇 가지 작은 예를 보는 것이 Haskell을 과시하는 가장 좋은 방법이 아니라는 데 동의합니다. 하지만 어쨌든 조금 줄 게요. 다음은 오일러 프로젝트 문제 18 및 67에 대한 초고속 솔루션 으로, 삼각형의 밑면에서 정점까지의 최대 합 경로를 찾도록 요청합니다.

bottomUp :: (Ord a, Num a) => [[a]] -> a
bottomUp = head . bu
  where bu [bottom]     = bottom
        bu (row : base) = merge row $ bu base
        merge [] [_] = []
        merge (x:xs) (y1:y2:ys) = x + max y1 y2 : merge xs (y2:ys)

다음은 Lesh와 Mitzenmacher가 작성한 BubbleSearch 알고리즘 의 완전하고 재사용 가능한 구현입니다 . DVD에 보관 용으로 대용량 미디어 파일을 낭비없이 포장하는 데 사용했습니다.

data BubbleResult i o = BubbleResult { bestResult :: o
                                     , result :: o
                                     , leftoverRandoms :: [Double]
                                     }
bubbleSearch :: (Ord result) =>
                ([a] -> result) ->       -- greedy search algorithm
                Double ->                -- probability
                [a] ->                   -- list of items to be searched
                [Double] ->              -- list of random numbers
                [BubbleResult a result]  -- monotone list of results
bubbleSearch search p startOrder rs = bubble startOrder rs
    where bubble order rs = BubbleResult answer answer rs : walk tries
            where answer = search order
                  tries  = perturbations p order rs
                  walk ((order, rs) : rest) =
                      if result > answer then bubble order rs
                      else BubbleResult answer result rs : walk rest
                    where result = search order

perturbations :: Double -> [a] -> [Double] -> [([a], [Double])]
perturbations p xs rs = xr' : perturbations p xs (snd xr')
    where xr' = perturb xs rs
          perturb :: [a] -> [Double] -> ([a], [Double])
          perturb xs rs = shift_all p [] xs rs

shift_all p new' [] rs = (reverse new', rs)
shift_all p new' old rs = shift_one new' old rs (shift_all p)
  where shift_one :: [a] -> [a] -> [Double] -> ([a]->[a]->[Double]->b) -> b
        shift_one new' xs rs k = shift new' [] xs rs
          where shift new' prev' [x] rs = k (x:new') (reverse prev') rs
                shift new' prev' (x:xs) (r:rs) 
                    | r <= p    = k (x:new') (prev' `revApp` xs) rs
                    | otherwise = shift new' (x:prev') xs rs
                revApp xs ys = foldl (flip (:)) ys xs

이 코드는 임의의 횡설수설처럼 보입니다. 그러나 Mitzenmacher의 블로그 항목 을 읽고 알고리즘을 이해 한다면 검색하려는 내용에 대해 아무 말없이 알고리즘을 코드로 패키지화 할 수 있다는 사실에 놀랄 것입니다.

요청한대로 몇 가지 예를 들었 으므로 Haskell을 이해 하는 가장 좋은 방법 은 DVD 패커를 작성하는 데 필요한 아이디어를 제공하는 논문을 읽는 것 입니다. John Hughes의 기능적 프로그래밍이 중요한 이유 . 이 논문은 실제로 Haskell보다 앞서 있지만 Haskell과 같은 사람들을 만드는 아이디어 중 일부를 훌륭하게 설명합니다.


5

저에게 Haskell의 매력은 컴파일러가 정확성을 보장 한다는 약속입니다 . 코드의 순수한 부분을위한 것이더라도.

나는 많은 과학적 시뮬레이션 코드를 작성했고, 이전 코드에 버그가 있었는지, 많은 현재 작업을 무효화 할 수 있는지에 대해 여러 번 궁금해 했습니다.


6
정확성을 어떻게 보장합니까?
Jonathan Fischoff

코드의 순수한 부분은 순수한 부분보다 훨씬 더 안전합니다. 신뢰 / 노력 투자 수준이 훨씬 높습니다.
롤 플레잉

1
그 인상을 준 것은 무엇입니까?
JD

5

특정 작업에서 Haskell을 사용하면 생산성이 매우 높습니다.

그 이유는 간결한 구문과 테스트의 용이성 때문입니다.

함수 선언 구문은 다음과 같습니다.

foo a = a + 5

이것이 제가 함수를 정의 할 수있는 가장 간단한 방법입니다.

역으로 쓰면

inverseFoo a = a-5

나는 작성하여 임의의 입력에 대해 역인지 확인할 수 있습니다.

prop_IsInverse :: Double-> Bool
prop_IsInverse a = a == (inverseFoo $ foo a)

그리고 명령 줄에서 호출

jonny @ ubuntu : runhaskell quickCheck + names fooFileName.hs

입력을 무작위로 테스트하여 내 파일의 모든 속성이 유지되는지 확인합니다.

Haskell이 모든 것을위한 완벽한 언어라고 생각하지는 않지만, 작은 함수를 작성하고 테스트 할 때 더 좋은 것을 보지 못했습니다. 프로그래밍에 수학적 구성 요소가 있다면 이것은 매우 중요합니다.


어떤 문제를 해결하고 있으며 어떤 다른 언어를 사용해 보셨습니까?
JD

1
모바일 및 iPad 용 실시간 3D 그래픽.
Jonathan Fischoff

3

Haskell의 유형 시스템에 머리를 감쌀 수 있다면 그 자체로 상당한 성취라고 생각합니다.


1
무엇을 얻을 수 있습니까? 필요한 경우 "data"== "class"및 "typeclass"= "interface"/ "role"/ "trait"를 생각하십시오. 이보다 더 간단 할 수는 없습니다. (엉망 당신을 심지어 "널 (null)"이 아닌 널은 당신이 당신의 유형 자신에 구축 할 수있는 개념이다..)
jrockway

8
얻을 게 너무 많아, jrockway. 여러분과 저는 그것이 상대적으로 간단하다고 생각하지만, 많은 사람들, 심지어 많은 개발자들조차도 특정한 종류의 추상화를 이해하기가 매우 어렵다고 생각합니다. 매일 사용하더라도 더 많은 주류 언어로 된 포인터와 참조에 대한 아이디어를 아직 이해하지 못하는 개발자를 많이 알고 있습니다.
그레고리 Higley

2

루프 구조가 없습니다. 많은 언어가 이러한 특성을 가지고 있지 않습니다.


17
ghci> : m + Control.Monad ghci> forM_ [1..3] print 1 2 3
sastanin

1

나는 함수형 프로그래밍이 프로그래밍을 다른 각도에서 보도록 당신의 두뇌를 비틀 었다는 말에 동의합니다. 애호가로만 사용했지만 문제에 접근하는 방식이 근본적으로 바뀌 었다고 생각합니다. Haskell에 노출되지 않고 (그리고 Python에서 생성기와 목록 이해를 사용하지 않고) LINQ를 사용하면 거의 효과가 없었을 것이라고 생각합니다.


-1

반대되는 견해를 표명 하기 위해 : Steve Yegge는 Hindely-Milner 언어가 좋은 시스템을 작성하는 데 필요한 유연성이 부족하다고 썼습니다 .

HM은 완전히 쓸모없는 형식적인 수학적 의미에서 매우 예쁩니다. 몇 가지 계산 구조를 매우 잘 처리합니다. Haskell, SML 및 OCaml에서 발견되는 패턴 매칭 디스패치가 특히 편리합니다. 당연히 다른 일반적이고 매우 바람직한 구조를 기껏해야 어색하게 처리하지만, 그들은 당신이 착각하고 실제로 원하지 않는다고 말함으로써 이러한 시나리오를 설명합니다. 아시다시피, 오, 변수 설정과 같은 것들이 있습니다.

Haskell은 배울 가치가 있지만 나름의 약점이 있습니다.


5
강력한 타입 시스템은 일반적으로 그것들을 고수해야한다는 것은 사실이지만 (그것이 그 강점을 유용하게 만드는 것입니다), 기존의 많은 (대부분?) HM 기반 타입 시스템이 실제로 일종의 ' 이스케이프 해치 '링크에 설명 된대로 (O'Caml에서 Obj.magic을 예로 들어 보겠습니다. 그러나 실제로는 많은 종류의 프로그램에서 그러한 장치가 필요하지 않습니다.
Zach Snow

3
변수 설정이 "바람직한"지 여부에 대한 질문은 대체 구문을 사용하는 것이 얼마나 고통 스러운지와 변수 사용으로 인한 고통의 정도에 달려 있습니다. 그것은 전체 주장을 기각하는 것이 아니라, "변수는 매우 바람직한 구조"라는 말을 공리로 취하는 것이 합당한 주장의 기초가 아니라는 점을 지적하는 것입니다. 대부분의 사람들이 프로그래밍 방법을 배우는 방식입니다.
gtd

5
-1 : 스티브의 진술은 부분적으로 구식이지만 대부분 완전히 사실적으로 잘못되었습니다. OCaml의 완화 된 값 제한과 .NET의 유형 시스템은 그의 진술에 대한 몇 가지 명백한 반대 사례입니다.
JD

4
Steve Yegge는 정적 타이핑에 대해 그의 보닛에 불합리한 벌을 가지고 있으며, 그가 말한 대부분이 잘못되었을뿐만 아니라 가능한 모든 기회 (그리고 일부 사용할 수없는 기회까지)에 대해 계속해서 제기합니다. 이와 관련하여 자신의 경험만을 신뢰하는 것이 좋습니다.
ShreevatsaR

3
정적 및 동적 타이핑에 대해 Yegge에 동의하지 않지만 Haskell에는 Data.Dynamic 유형이 있습니다. 다이나믹 타이핑을 원한다면 할 수 있습니다!
jrockway
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.