如何将Scheme程序转换为Haskell?

时间:2010-11-09 03:14:00

标签: haskell scheme

我要将一个方案程序转换为Haskell,但我很难学习Haskell的所有内容。如果您熟悉SICP,我的任务是回答练习3.63,3.64,3.65,3.66和3.71。我已经找到了这些问题的答案,但它们是用方案编写的。以下是3.63中的问题和答案:

  

练习3.63。 Louis Reasoner问为什么sqrt-stream过程不是以下面更直接的方式编写的,没有局部变量猜测:

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

Alyssa P. Hacker回复说,这个版本的程序效率低得多,因为它执行冗余计算。

     

解释Alyssa的回答。

     

如果我们的延迟实现仅使用(lambda () <exp>)而不使用memo-proc(第3.5.1节)提供的优化,那么这两个版本的效率是否会有所不同?

答案:

  

在Louis Reasoner的程序中,在(sqrt-stream x)内递归调用(sqrt-stream x)。但是,这两个流不是同一个变量。因此,执行冗余计算。在原始版本中,使用局部变量猜测。

(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))

这是我写的Haskell代码,它不起作用:

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

请帮我修改我的代码。我下周需要它们。

我还会尝试其他的并在此处发布,如果再次出现错误的话。希望你能帮帮我。谢谢。

1 个答案:

答案 0 :(得分:2)

您的Haskell代码在如此多的级别上看起来是错误的(例如,没有循环结构,您无法分配新的值来猜测)。我只能猜到你想要的东西。这是一个计算平方根的函数:

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)

这是一个版本,它为您提供近似值列表(直到它不再改变):

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)