불순한 언어는 원칙적으로 더 친숙한 명령형 언어와 크게 다르지 않으며, 특히 많은 기능적 트릭이 복사되었습니다. 다른 점은 스타일입니다. 문제를 해결하는 방법입니다.
Haskell을 순수한 것으로 계산하든 IO 모나드를 불순물로 계산하든 Haskell 스타일은이 스타일의 극단적 인 형태이며 학습 가치가 있습니다.
Haskell IO 모나드는 모나드의 수학 이론에서 비롯됩니다. 그러나 명령형 프로그래머의 경우 모나드에 역방향으로 도달하는 것이 더 합리적이라고 생각합니다.
1 단계-순수한 기능 언어는 결과로 큰 문자열 값을 쉽게 반환 할 수 있습니다. 이 큰 문자열은 요구 사항 지정 매개 변수에서 순수한 기능 방식으로 파생 된 명령형 프로그램의 소스 코드 일 수 있습니다. 그런 다음 코드 생성기를 실행하는 "상위 레벨"컴파일러를 빌드 한 다음 생성 된 코드를 명령형 언어 컴파일러에 자동으로 공급할 수 있습니다.
2 단계-텍스트 소스 코드를 생성하지 않고 강력한 형식의 추상 구문 트리를 생성합니다. 명령형 언어 컴파일러는 "상위 레벨"컴파일러에 흡수되어 AST를 소스 코드로 직접 허용합니다. 이것은 Haskell이하는 일에 훨씬 가깝습니다.
그래도 여전히 어색합니다. 예를 들어, 코드 생성 단계에서 평가 된 기능과 생성 된 프로그램이 실행될 때 실행되는 두 가지 고유 한 기능이 있습니다. C ++에서 함수와 템플릿을 구별하는 것과 약간 비슷합니다.
따라서 3 단계의 경우 두 코드를 동일하게 만듭니다. 동일한 코드를 가진 동일한 함수는 "코드 생성"중에 부분적으로 평가되거나 완전히 평가되거나 전혀 평가되지 않을 수 있습니다. 또한 재귀를 위해 모든 루핑 구성 AST 노드를 삭제하십시오. 실제로, AST 노드에 대한 아이디어를 특별한 종류의 데이터로 버리십시오. "리터럴 값"AST 노드는없고 값만 있습니다.
이것은 IO 모나드가하는 것과 거의 같습니다. 바인드 연산자는 "동작"을 구성하여 프로그램을 형성하는 방법입니다. 특별한 것은 아닙니다-단지 기능입니다. "코드 생성"중에 많은 표현식과 함수를 평가할 수 있지만 I / O 부작용에 의존하는 함수는 런타임까지 평가가 지연되어야합니다. 특별한 규칙이 아니라 데이터 종속성의 자연스러운 결과입니다. 표현.
모나드는 일반적으로 일반화입니다. 인터페이스는 동일하지만 추상 연산을 다르게 구현하므로 명령형 코드에 대한 설명을 평가하는 대신 다른 것으로 평가합니다. 동일한 인터페이스를 사용한다는 것은 어떤 모나드를 신경 쓰지 않고 모나드에 할 수있는 일이 있다는 것을 의미합니다.
이 설명은 의심의 여지없이 순수 주의자들의 머리를 폭발시킬 것이지만 나에게 Haskell이 흥미로운 이유를 설명해줍니다. 프로그래밍과 메타 프로그래밍 사이의 경계를 흐리게하고 기능 프로그래밍 도구를 사용하여 특별한 구문없이 명령형 프로그래밍을 재창조합니다.
C ++ 템플릿에 대한 비판은 그것들이 명령형 언어로 깨진 순수한 기능 하위 언어라는 것입니다. 런타임이 아닌 컴파일 타임에 동일한 기본 기능을 평가하려면 완전히 다른 스타일을 사용하여 다시 구현해야합니다 코딩 Haskell에서, 불순물은 그 유형으로 라벨링되어야하지만, 동일한 프로그램에서 메타 프로그래밍 의미와 런타임 비 메타 프로그래밍 의미로 정확하게 동일한 기능이 평가 될 수 있습니다. 프로그래밍과 메타 프로그래밍 사이.
즉, 표준 Haskell이 수행 할 수없는 메타 프로그래밍 작업이 있습니다. 기본적으로 유형 (및 기타 몇 가지)이 일류 값이 아니기 때문입니다. 그러나이 문제를 해결하려는 언어 변형이 있습니다.
Haskell에 대해 말한 많은 것들이 불완전한 기능적 언어, 때로는 명령형 언어로 적용될 수 있습니다. Haskell은 선택의 여지가 없기 때문에 다릅니다.이 접근법을 취해야합니다. 기본적 으로이 작업 스타일을 배우도록 강요합니다. "ML로 C를 쓸 수는 있지만" "하스켈에 C를 쓸 수는 없습니다".