Seperti yang dikatakan Telastyn: Secara teknis, ya, kecuali ada beberapa cara dalam bahasa Anda untuk menjamin bahwa fungsi input juga murni.
Itu bukan hipotesis, memang ada cara yang baik untuk menjamin ini. Setidaknya dalam bahasa yang sangat diketik.
Seperti fungsi ~ murni yang akan Anda tulis dalam JavaScript
function foo(f) {
return f(1) + 2;
}
dapat diterjemahkan langsung ke Haskell:
foo :: (Int -> Int) -> Int
foo f = f 1 + 2
Sekarang, di JavaScript Anda bisa melakukan hal-hal jahat
js> foo (function(x) {console.log("muharhar"); return 0})
muharhar
2
Ini tidak mungkin di Haskell . Alasannya, sesuatu seperti efek samping console.log()
harus selalu memiliki tipe hasil IO something
, tidak hanya something
sendirian.
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)
Untuk ekspresi ini untuk mengetik centang, kita perlu memberikan foo
tanda tangan jenis
foo :: (Int -> IO Int) -> Int
Tapi ternyata saya tidak bisa mengimplementasikannya lagi: karena fungsi argumen ada IO
di hasilnya, saya tidak bisa menggunakannya di dalamnya 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
Satu-satunya cara saya bisa menggunakan IO
tindakan foo
adalah jika hasil foo
memiliki tipe IO Int
itu sendiri:
foo :: (Int -> IO Int) -> IO Int
foo f = do
f1 <- f 1
return (f1 + 2)
Tetapi pada titik ini jelas dari tanda tangan foo
bahwa itu juga bukan fungsi murni.
foo = function(function bar){ print(bar.toString()) }