Telastyn'in dediği gibi: Teknik olarak, evet, giriş işlevinin de saf olduğunu garanti etmenin bir yolu yoksa.
Bu varsayımsal değil, bunu garanti etmenin gerçekten iyi yolları var. En azından kuvvetle yazılmış bir dilde.
JavaScript'te yazacağınız gibi saf bir işlev
function foo(f) {
return f(1) + 2;
}
doğrudan Haskell'e çevrilebilir:
foo :: (Int -> Int) -> Int
foo f = f 1 + 2
Şimdi JavaScript'te kötü şeyler yapabilirsiniz
js> foo (function(x) {console.log("muharhar"); return 0})
muharhar
2
Haskell'de bu mümkün değil . Nedeni, yan etki gibi console.log()
bir IO something
şey sadece something
yalnız değil, her zaman bir sonuç türüne sahip olmalıdır .
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)
Bu ifadenin daktiloyu kontrol etmesi foo
için tür imzası vermemiz gerekir
foo :: (Int -> IO Int) -> Int
Ama o zaman artık uygulayamadığım ortaya çıkıyor: çünkü argüman işlevi IO
sonuçta olduğu için onu kullanamıyorum 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
Bir IO
eylem kullanabilmenin tek yolu foo
sonucu foo
tür IO Int
kendisi ise:
foo :: (Int -> IO Int) -> IO Int
foo f = do
f1 <- f 1
return (f1 + 2)
Ancak bu noktada foo
, bunun saf bir işlev olmadığı imzasından da anlaşılmaktadır .
foo = function(function bar){ print(bar.toString()) }