하스켈에서 인쇄 된 순수 함수입니다. 그 이유는 무엇? 나는 순수한 함수가 항상 같은 값을 반환하지 않기 때문에 그것이 아니라고 생각하고있다.Haskell이 순수한 함수로 인쇄 되었습니까?
답변
순수 함수의 태그 (동일한 인수 값에서 항상 동일한 결과 값을 평가하고 의미 상 관찰 가능한 부작용이나 출력을 발생시키지 않는 함수, 예를 들어, ., 없음 ... 그것을 당신은 항상 IO()
를 반환,이 트릭을 찾을 수
putStrLn :: String -> IO()
: 그래서, 다음 가변 객체 또는 출력 I/O 장치에 대한)과 인쇄의 종류에 생각 효과를냅니다. 따라서 Referential Transparency은 순수하지 않습니다. 예를 들어 getLine
은 IO String
을 반환하지만 순수 함수이기도합니다. (@interjay 기여도), 내가 말할 노력하고있어, 대답은 질문의 매우 가까이 달려 있다는 것입니다 :
가치의 문제에 IO()
는 항상 동일한 입력에 대해 동일한 IO()
값이됩니다. 그 IO()
의 실행이 부작용 (이 경우 너무 순진한 모습에, 화면에 문자열을 넣어 가질 수 있기 때문에
과 실행의 문제에
, 그것은 순수한 것이 아니라 일부 IO 수 점심 핵 폭탄, 그리고 는 현재 @ 벤의 좋은 접근 방식을 더 잘 이해할 수
지능 42)을 반환 :
" 을"순수하게 "조작하는 방법을 설명하는 데는 여러 가지 방법이 있습니다. 하나는 IO가 상태 모나드와 같다고 말하면서 만 상태가 쓰여지고 프로그램 밖에있는 상태입니다 = (그래서 당신의 Stuff -> IO DBThing 함수는 세상을받는 여분의 숨겨진 인자를 가지고 있습니다 실제로 다른 세계와 함께 DBThing을 반환하며 항상 다른 세계에서 호출되므로 동일한 Stuff와 함께 호출 할 때 012TB_E_KR까지 다른 DBThing 값을 반환 할 수 있습니다. 또 다른 설명은 IO DBThing 값 자체가 명령형 프로그램이라는 것입니다. . 당신의 하스켈 프로그램은 IO를 수행 불순한 프로그램 을 반환하지 IO를 수행하지 않는 완전히 순수 기능, 하스켈 런타임 시스템 (impurely) "가 반환 프로그램을 실행
그리고 @Erik Allik 입니다 : 입력 IO (A)의 값을 반환 런타임에서 실행되고 있지 기능이 실제로
그래서 하스켈 기능 -. 실행됩니다 무슨 일이 그래서 이러한 기능은 실제로 순수하지만 자신을 값 자체 IO입니다 반환 값은 비 목적을 나타냅니다. 전자 계산.당신이 할 수있는
형 IO Int
의 값은 정말 Int
하지 여기 Understanding pure functions in Haskell with IO
Sneaky Haskell :) – HFBrowning
@HFBrowning 그래서 규칙이 있습니다. 그래서 모나드가 규칙을 따르는 이유는 모두가 haskell을 좋아하는 이유입니다. 일단 여러분이 그것의 일부를 작성하면, 순수한 함수, 순수한 사랑 ahaahah –
분명히 타입에 필요하기 때문에 항상 IO()를 반환합니다. 그러나 질문은 그것은 항상'IO()'의 _same_ 값을 반환합니다. – Lee
을 발견했다. 이것은 "하스켈 런타임과 같은 방식으로 Int
값을 생산하십시오."라고 읽는 종이와 비슷합니다. 이 종이는 비활성이며 결국 런타임에 의해 생성 된 Int
이 다른 경우에도 동일하게 유지됩니다.
main
에 할당하여 런타임에 종이를 보냅니다. IO
동작이 main
의 방식으로 절대로 발생하지 않고 일부 컨테이너 내부에서 절름발이 인 경우 절대로 실행되지 않습니다.
IO
작업을 반환하는 함수는 다른 함수와 마찬가지로 순수합니다. 그들은 항상 같은 종이를 반환합니다. 이러한 지침으로 런타임이 수행하는 작업은 또 다른 문제입니다. 그들은 순수 '의 t을 weren 히 경우
, 우리는 print
순수 함수,
foo :: (Int -> IO Int) -> IO Int
foo f = let x = f 0 in liftA2 (+) x x
런타임에 'IO X'와 'X'는 실제로 같은 방식으로 표현됩니다. 컴파일러는'IO X'가 어떻게 동작하는지에 대한 특별한 것들을 알고 있습니다 (그리고 순수한 값들이 어떻게 동작하는지에 대한 특별한 것들 - 위반할 수있는 가정들)! 이 가정을 사용하여 최적화 된 코드를 생성합니다. 지침 (즉, "종이 조각")으로서의 IO의 관점은 여전히 유용합니다. 그러나 '실행 시점의 가치'와 관련해서 생각해서는 안되며, '논리적 인 객체로서의 가치'와 관련해서는 안됩니다. – user2407038
@ user2407038 적어도 GHC에서 'IO X'는 [매우 다른 표현입니다] (https://hackage.haskell.org/package/base-4.10.0.0/docs/src/GHC.Base.html#line- 1197). –
예에
foo :: (Int -> IO Int) -> IO Int
foo f = liftA2 (+) (f 0) (f 0)
을 변경하기 전에 두 번 생각해야합니다. 반환하는 값은 IO()
유형이며, 전달한 문자열을 출력하는 코드 묶음으로 생각할 수 있습니다. 전달한 각 문자열에 대해 항상 동일한 코드가 반환됩니다.
'print'는 무엇을 반환합니까? –
내장 된 모든 불순한 기능에는 이름에'unsafe'라는 단어가 있습니다. 그래서'print'는 순수합니다. 동일한 매개 변수가 주어지면 동일한 결과를 반환합니다. – 4castle
@ 4castle 필연적 인 것은 아니지만 대개 '안전하지 않은 것'은 함수가 합계가 아니라는 사실에 관한 것입니다. – freestyle