En essayant d'apprendre Haskell, j'ai implémenté un calcul de pi afin de comprendre correctement les fonctions et la récursivité.Dépassement de pile dans GHCI lorsque vous tentez d'afficher un nombre
Utilisation du Leibniz Formula pour calculer pi, je suis venu avec ce qui suit, qui imprime pi à la tolérance du paramètre donné, et le nombre de fonction récursive appels afin d'obtenir cette valeur:
reverseSign :: (Fractional a, Ord a) => a -> a
reverseSign num = ((if num > 0
then -1
else 1) * (abs(num) + 2))
piCalc :: (Fractional a, Integral b, Ord a) => a -> (a, b)
piCalc tolerance = piCalc' 1 0.0 tolerance 0
piCalc' :: (Ord a, Fractional a, Integral b) => a -> a -> a -> b -> (a, b)
piCalc' denom prevPi tolerance count = if abs(newPi - prevPi) < tolerance
then (newPi, count)
else piCalc' (reverseSign denom) newPi tolerance (count + 1)
where newPi = prevPi + (4/denom)
Alors, quand je lance cela dans GHCi, il semble fonctionner comme prévu:
*Main> piCalc 0.001
(3.1420924036835256,2000)
Mais si je mets ma tolérance trop fine, cela se produit:
*Main> piCalc 0.0000001
(3.1415927035898146,*** Exception: stack overflow
Cela me semble totalement contre-intuitif; le calcul réel fonctionne bien, mais juste en essayant d'imprimer combien d'appels récursifs échoue ??
Pourquoi est-ce ainsi?
Dans le cas où vous ne savez pas ce qu'est un thunk (ce que je n'ai pas fait quand j'ai commencé Haskell!) C'est fondamentalement un calcul non résolu. Dans votre premier exemple, avant d'imprimer count, il n'aura pas la valeur de 2000, il aura une valeur de ... +1) +1 +1) +1 +1 (J'ai omis les parenthèses gauches de 2000 au début: P). Lorsque vous imprimez cela, il est effectivement ajouté. –
Je vais juste ajouter à ce que @DanielBuckmaster a dit que le point important est alors que les thunks continuent de s'accumuler, prenant de plus en plus de mémoire, alors que l'on s'attend naïvement 'count' à quelque chose comme un' Int' (constant dans l'espace) . Vous vous habituerez à cela, mais c'est certainement quelque chose qui peut vous mordre. – gspr