2010-11-09 7 views
2

Je vais transformer un programme en Haskell, mais j'ai du mal à tout apprendre sur Haskell. Si vous connaissez SICP, je suis chargé de répondre aux exercices 3.63, 3.64, 3.65, 3.66 et 3.71. J'ai déjà trouvé les réponses à ces problèmes mais ils sont écrits en schéma. Voici la question et la réponse en 3.63:Comment transformer le programme Scheme en Haskell?

Exercice 3.63. Louis Reasoner demande pourquoi la procédure sqrt flux n'a pas été écrit dans ce qui suit de façon plus simple, sans les variables locales: suppositions

(define (sqrt-stream x) 
    (cons-stream 1.0 
    (stream-map (lambda (guess) 
    (sqrt-improve guess x)) 
    (sqrt-stream x)))) 

Alyssa P. Hacker répond que cette version de la procédure est beaucoup moins efficace parce qu'il exécute calcul redondant.

Expliquez la réponse d'Alyssa.

Les deux versions seraient-elles encore différentes en termes d'efficacité si notre implémentation de délai n'utilisait que (lambda() <exp>) sans utiliser l'optimisation fournie par memo-proc (section 3.5.1)?

Réponse:

Dans la procédure de Louis Reasoner, (sqrt-stream x) est récursive appelé à l'intérieur (sqrt-stream x). Cependant, les deux flux ne sont pas la même variable. Par conséquent, le calcul redondant est effectué. Dans la version originale, une variable locale est utilisée.

(define (sqrt-stream x) 
    (define guesses 
    (cons-stream 1.0 
     (stream-map (lambda (guess) 
      (sqrt-improve guess x)) 
        guesses))) 
    guesses) 
(display-stream (sqrt-stream 2)) 

Voici le code Haskell que je l'ai écrit et il ne fonctionne pas:

module Main 
where 
guess = 1:: Double 
x=0 
do 
if ((guess*guess) = x) 
    then y = (x + guess)/x 
    guess = y 
else 
    sqrt x = guess 

S'il vous plaît me aider à résoudre mes codes. J'ai besoin d'eux la semaine prochaine.

Je vais aussi essayer les autres et les poster ici s'il y aura des erreurs à nouveau. J'espère que vous pouvez m'aider. Merci beaucoup.

+0

devrait être mis sur stackoverflow, mais ce erreurs obtenez-vous? Est-ce que ça va compiler? – oadams

+1

Votre code Haskell ne ressemble pas du tout à la réponse Scheme. Qu'est-ce que 'sqrt-improvement'? – kennytm

+3

Je suggèrerais que vous passiez en revue quelques tutoriels introductifs Haskell pour mieux comprendre la syntaxe du langage. Essayez http://learnyouahaskell.com/chapters ou peut-être http://book.realworldhaskell.org/read/ –

Répondre

2

Votre code Haskell semble erroné sur tant de niveaux (par exemple, il n'y a pas de construction de boucle, vous ne pouvez pas attribuer une nouvelle valeur à deviner). Je peux seulement deviner ce que tu veux. Voici une fonction de calcul de la racine carrée:

sqrt' :: Double -> Double 
sqrt' n = loop n 
    where loop guess | abs (guess - improve guess) < 0.00000000001 = improve guess 
        | otherwise = loop $ improve guess 
      improve guess = 0.5 * (guess + n/guess) 

est ici une version qui vous donne la liste des approximations (jusqu'à ce qu'elle ne change pas plus):

sqrt' :: Double -> [Double] 
sqrt' n = takeChanging $ iterate (\ guess -> 0.5 * (guess + n/guess)) n 
      where takeChanging (x:y:ys) | abs (x-y) < 0.00000000001 = [x] 
             | otherwise = x : takeChanging (y:ys) 
Questions connexes