Telastynが言ったように:技術的には、はい、あなたの言語に入力関数も純粋であることを保証する方法がない限り。
これは仮説ではありません。これを保証する良い方法は確かにあります。少なくとも強く型付けされた言語では。
JavaScriptで次のように記述するようなpure〜関数
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ではこれは不可能です。その理由は、副作用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()) }