Supposons que vous ayez une fonction nulle dans HASKELLL, qui est utilisée plusieurs fois dans le code. Est-ce toujours évalué qu'une seule fois? J'ai déjà testé le code suivant:
test _ 0 = [] test s n = (s:(test (n-1))) ... test sayHello 10
3 Réponses :
Il n'y a pas de fonctionnalité nullaire. Une fonction de Haskell a exactement un argument et a toujours le type sur les garanties: Non, vous n'obtenez pas vraiment de garanties. Le rapport HASKELL Spécifie que Haskell n'est pas strict - vous savez donc quelles sont les choses de la valeur qui finiront par réduire - mais pas une stratégie d'évaluation particulière. La stratégie d'évaluation GHC utilise généralement est évaluation paresseuse , c'est-à-dire une évaluation non stricte avec le partage, mais cela ne Il faut des garanties fortes à ce sujet - l'optimiseur pourrait mélanger votre code autour de sorte que les choses soient évaluées plus d'une fois. P>
Il existe également différentes exceptions - par exemple, ... -> ... code>.
Sayhello code> est une valeur - un
int code> - mais pas une fonction. Voir Cet article Pour plus. P>
foo :: num A => A code> est polymorphe, il ne sera probablement pas partagé (il est compilé à une fonction réelle). Parfois, une valeur pure peut être évaluée par plus d'un fil en même temps (qui ne se produira pas dans ce cas car
inadaperformio code> utilise explicitement
noduplicate code> pour l'éviter). Ainsi, lorsque vous programmez, vous pouvez généralement attendre la paresse em>, mais si vous voulez une sorte de garantie, vous devez faire très attention. Le rapport lui-même ne vous donnera rien vraiment sur comment em> votre programme est évalué. P>
Unsafeperformio code> vous donne encore moins dans la voie des garanties, bien sûr. Il y a une raison pour laquelle il s'appelle "dangereux". P>
Niveau supérieur Niveau non-argument Fonctions telles que Modifier em>: Devis du lien ci-dessus - P>
Haskell est un langage paresseux et certaines expressions ne sont que jamais
évalué une fois. Par exemple, si nous écrivons:
Sayhello CODE> sont appelées formes applicatives constantes et sont toujours mémoisées (au moins dans GHC - voir
x = nfib 25 code> alors
x code> ne sera évalué qu'une seule fois (le tout), et
Les demandes ultérieures pour
x code> vont immédiatement voir le résultat mis en cache.
La définition
x code> est appelée formulaire de CAF (formulaire d'application constante), car
Il n'a aucun argument. P>
blockQuote>
Si vous voulez "Bonjour" imprimé n Times, vous devez supprimer le nonafeperformio indicatif>, de sorte que l'exécution saura qu'elle ne peut pas optimiser les appels répétés vers
Poststr CODE> . Je ne suis pas clair si vous souhaitez renvoyer la liste des int, j'ai donc écrit deux versions de test, l'une des revenues (), une [int].
sayHello2 :: IO Int
sayHello2 = do
putStr "Hello"
return 42
test2 :: Int -> IO ()
test2 0 = return ()
test2 n = do
sayHello2
test2 (n-1)
test3 :: Int -> IO [Int]
test3 0 = return []
test3 n = do
r <- sayHello2
l <- test3 (n-1)
return $ r:l