Telastyn이 말했듯이 : 기술적으로는 입력 기능도 순수하다는 것을 보장 할 수있는 방법이 없다면 말입니다.
그것은 가설이 아니며 실제로 이것을 보장하는 좋은 방법이 있습니다. 최소한 강력한 형식의 언어로되어 있어야합니다.
JavaScript에서 쓸 수있는 순수한 함수는
function foo(f) {
return f(1) + 2;
}
Haskell로 직접 번역 될 수 있습니다 :
foo :: (Int -> Int) -> Int
foo f = f 1 + 2
이제 JavaScript에서 다음과 같은 악의적 인 일을 할 수 있습니다
js> foo (function(x) {console.log("muharhar"); return 0})
muharhar
2
Haskell에서는 불가능합니다 . 이유 존재, 뭔가 부작용-FUL 같은 console.log()
필수는 항상 결과 유형이 IO something
아니라, something
혼자.
GHCi> foo (\x -> print "muarhar" >> return 0)
<interactive>:7:12:
Couldn't match expected type ‘Int’ with actual type ‘IO b0’
In the expression: print "muarhar" >> return 0
In the first argument of ‘foo’, namely
‘(\ x -> print "muarhar" >> return 0)’
In the expression: foo (\ x -> print "muarhar" >> return 0)
이 표현식을 타입 체크 foo
하려면 타입 시그니처 를 제공해야합니다.
foo :: (Int -> IO Int) -> Int
그러나 그것은 더 이상 그것을 구현할 수 없다는 것이 밝혀졌습니다 : 인수 함수 IO
의 결과로 인해에서 사용할 수 없습니다 foo
.
<interactive>:8:44:
Couldn't match expected type ‘Int’ with actual type ‘IO Int’
In the first argument of ‘(+)’, namely ‘f 1’
In the expression: f 1 + 2
내가 IO
액션을 사용할 수있는 유일한 방법 foo
은 결과 자체에 foo
유형 이있는 경우 IO Int
입니다.
foo :: (Int -> IO Int) -> IO Int
foo f = do
f1 <- f 1
return (f1 + 2)
그러나이 시점에서 그것이 foo
순수한 기능이 아니라는 서명에서 분명 합니다.
foo = function(function bar){ print(bar.toString()) }