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 somethingyalnı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 fooiç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 IOsonuç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 IOeylem kullanabilmenin tek yolu foosonucu footür IO Intkendisi 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()) }