2017-01-24 10 views
3

하스켈을 배우기 시작한 후 많은 문서를 읽은 후에도 하스켈에서 이해할 수없는 무언가가 있습니다.기능 프로그래밍 : 실제로 부작용은 어디에서 발생합니까?

IO 작업을 수행하려면 IO 모나드를 사용하는 모든 함수가 여전히 순수하게 작동 할 수 있도록 "블랙 박스"종류의 값을 래핑 한 "IO 모나드"를 사용해야한다는 것을 알고 있습니다. 좋아요. 그렇지만 입출력 작업은 실제로 어디에서 발생합니까?

모나드 자체가 순전히 기능적이지 않다는 의미입니까? 또는 IO 연산이 구현 되었습니까? C와 Haskell 컴파일러에 "임베디드"라고 가정 해 봅시다.

모나드가 있거나 없거나 순수한 하스켈에서 IO 연산을 수행 할 수 있습니까? 그리고 만약 그렇지 않다면 언어 자체 내에서 가능하지 않다면이 능력은 어디서 오는 것입니까? 그것이 Haskell 컴파일러 내부에 C 코드 조각에 내장/링크되어 있다면, IO Monad가 "더러운 일"을하도록 결국 호출 할 것입니까?

+1

(100 % 확신 할 수 없기 때문에 논평하고 있습니다.) 제 이해는 IO가 상태로 "실제 세계"가있는 저레벨 상태 모나드로 모델링된다는 것입니다. 컴파일러/런타임은 실제로이를 운영 체제 API에 대한 바인딩을 사용하여 구현 된 IO 작업으로 변환합니다. 순전히 함수형 프로그래밍은 아무 것도 계산할 수 없지만 아무에게도 말하지 않을 수 있습니다. 실제 상황에서 이러한 상태 저장 액션을 기본 운영 체제에 대한 실제 호출로 변환 할 수있는 런타임이 필요합니다. – bheklilr

+0

https://wiki.haskell.org/IO_inside#Welcome_to_the_RealWorld.2C_baby –

답변

17

서문으로, 서술 내용이 많은 서적에도 불구하고 "IOMonad"이 아닙니다. 그냥 "IO 유형"입니다. 모나드에는 마법 같은 것이 없습니다. Haskell의 Monad 클래스는 꽤 ​​지루한 일입니다. 대부분의 언어가 지원할 수있는 것보다 생소하고 추상적입니다. IOIOAlternative이라고하는 사람은 IOAlternative으로 구현 되어도 누구도 볼 수 없습니다. Monad에 집중하는 것은 학습의 길에 들어갑니다.

순수한 언어로 효과의 원칙 취급 (하지 부작용!)에 대한 개념 마법은 전혀 IO 유형의 존재이다. 그것은 진짜 유형입니다. "이것은 불결합니다!"라고 말하는 깃발이 아닙니다. 그것은 정확히 Maybe 또는 []과 같은 종류의 완전한 하스켈 종류 * -> *입니다. IO 값을 인수로 사용하는 서명 (예 : IO a -> IO (Maybe a))은 의미가 있습니다. 중첩 된 IO가있는 유형 서명은 의미가 있습니다 (예 : IO (IO a)).

실제 유형 인 경우 구체적인 의미가 있어야합니다. 유형으로 Maybe aa 유형의 누락 가능성 값을 나타냅니다. [a]a 유형의 0 이상의 값을 의미합니다. IO aa 유형의 값을 생성하는 일련의 효과를 의미합니다.

IO의 전체 목적은 일련의 효과를 나타내는 것입니다. 위에서 말했듯이, 그것들은 부작용이 아닙니다. 프로그램의 무해한 모양의 잎 속에 숨겨져서는 안되며 다른 코드 뒤에있는 것을 신비하게 바꿉니다. 대신 효과는 실제로는 IO 값이라는 사실에 의해 명시 적으로 호출됩니다. 이런 이유로 사람들은 IO 유형을 사용하여 프로그램의 일부를 최소화하려고 시도합니다. 당신이하는 일이 적을수록 프로그램에 방해가 될 정도로 거리낌없는 행동을하는 방법이 줄어 듭니다.

당신의 질문의 주된 견해로서, 완전한 하스켈 프로그램은 이라는 IO 값과 그것이 사용하는 정의의 모음입니다. 컴파일러는 코드를 생성 할 때 실질적으로 효과 시퀀스를 IO 값으로 실행하는 Haskell이 아닌 코드 블록을 삽입합니다. 어떤 의미에서 이것은 Simon Peyton Jones (GHC의 오랜 저자 중 한 명)가 그의 이야기에서 점점 더 가까워지고있는 것입니다. Haskell is useless.

실제로 IO 작업을 실행하는 모든 것이 개념적으로 순수하지 않을 수 있습니다.(그리고 Haskell 언어 내에서 IO 액션이 실행되는 매우 불순한 기능이 있습니다. 외국 함수 인터페이스를 지원하기 위해 추가 된 것보다 더 자세히 말하지는 않을 것이며 부적절하게 사용하면 프로그램이 매우 심하게 손상 될 것입니다.) 그러나 Haskell의 요점은 이펙트 시스템에 원칙적인 인터페이스를 제공하고 비 기본화 된 비트를 숨기는 것입니다. 그리고 실제로는 실제로 그렇게 유용합니다.