Je dirais que la meilleure chose à demander n'est pas comment nous l'appellerions, mais comment nous analyserions un tel code. Et ma première question clé dans une telle analyse serait:
- L'effet secondaire dépend-il de l'argument de la fonction ou du résultat de l'effet secondaire?
- Non: la "fonction efficace" peut être reformulée en une fonction pure, une action efficace et un mécanisme permettant de les combiner.
- Oui: la "fonction efficace" est une fonction qui produit un résultat monadique.
Ceci est simple à illustrer dans Haskell (et cette phrase n’est qu’une demi-plaisanterie). Un exemple du cas "non" serait quelque chose comme ceci:
double :: Num a => a -> IO a
double x = do
putStrLn "I'm doubling some number"
return (x*2)
Dans cet exemple, l'action que nous effectuons (imprimer la ligne "I'm doubling some number") n'a aucun impact sur la relation entre xet le résultat. Cela signifie que nous pouvons le refactoriser de cette manière (en utilisant la Applicativeclasse et son *>opérateur), ce qui montre que la fonction et l'effet sont en fait orthogonaux:
double :: Num a => a -> IO a
double x = action *> pure (function x)
where
-- The pure function
function x = x*2
-- The side effect
action = putStrLn "I'm doubling some number"
Donc, dans ce cas, je dirais personnellement que c'est un cas où vous pouvez factoriser une fonction pure. Cela concerne beaucoup de programmes Haskell - apprendre à décomposer les parties pures du code efficace.
Un exemple du type "oui", où les parties pures et effectives ne sont pas orthogonales:
double :: Num a => a -> IO a
double x = do
putStrLn ("I'm doubling the number " ++ show x)
return (x*2)
Maintenant, la chaîne que vous imprimez dépend de la valeur de x. La partie fonction (multiplier xpar deux), cependant, ne dépend pas du tout de l'effet, nous pouvons donc la factoriser:
logged :: (a -> b) -> (a -> IO x) -> IO b
logged function logger a = do
logger a
return (function a)
double x = logged function logger
where function = (*2)
logger x putStrLn ("I'm doubling the number " ++ show x)
Je pourrais continuer à donner d’autres exemples, mais j’espère que c’est suffisant pour illustrer le point que j’avais commencé: vous n’appelez pas quelque chose, vous analysez la relation entre les parties pure et efficace et les factorisez quand c’est le cas. à votre avantage.
C'est l'une des raisons pour lesquelles Haskell utilise Monadtellement sa classe. Les monades sont (entre autres) un outil pour effectuer ce type d’analyse et de refactorisation.