Comme Telastyn l'a dit: Techniquement, oui, à moins qu'il n'y ait un moyen dans votre langue de garantir que la fonction d'entrée est également pure.
Ce n'est pas hypothétique, il existe en effet de bons moyens de garantir cela. Au moins dans une langue fortement typée.
Une telle fonction ~ pure que vous écririez en JavaScript
function foo(f) {
return f(1) + 2;
}
peut être traduit directement en Haskell:
foo :: (Int -> Int) -> Int
foo f = f 1 + 2
Maintenant, en JavaScript, vous pouvez faire des trucs diaboliques comme
js> foo (function(x) {console.log("muharhar"); return 0})
muharhar
2
Ce n'est pas possible à Haskell . La raison en est que quelque chose d'effet secondaire console.log()
doit toujours avoir un type de résultat IO something
, pas seulement something
seul.
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)
Pour que cette expression soit vérifiée, nous aurions besoin de donner foo
la signature de type
foo :: (Int -> IO Int) -> Int
Mais il s'avère que je ne peux plus l'implémenter alors: parce que la fonction d'argument a IO
dans son résultat, je ne peux pas l'utiliser à l'intérieur 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
La seule façon dont je pourrais utiliser une IO
action foo
est si le résultat de foo
a IO Int
lui-même le type :
foo :: (Int -> IO Int) -> IO Int
foo f = do
f1 <- f 1
return (f1 + 2)
Mais à ce stade, il ressort clairement de la signature foo
que ce n'est pas une fonction pure non plus.
foo = function(function bar){ print(bar.toString()) }