簡體   English   中英

列表理解中的 Haskell 無限遞歸

[英]Haskell infinite recursion in list comprehension

我試圖定義一個函數,它接受一個點 (x,y) 作為輸入,並返回一個對應於遞歸調用的無限列表

P = (u^2 − v^2 + x, 2uv + y)

u 和 v 的初始值都是 0。

  • 第一個電話是

    P = (0^2 - 0^2 + 1, 2(0)(0) + 2) = (1,2)

  • 那么結果元組 (1,2) 將是 u 和 v 的下一個值,因此它將是

    P = (1^2 - 2^2 + 1, 2(1)(2) + 2) = (-2,6)

等等。

我想弄清楚如何在 Haskell 中對此進行編碼。 這是我到目前為止:

o :: Num a =>(a,a) -> [(a,a)]
o (x,y) = [(a,b)| (a,b)<- [p(x,y)(x,y)]]   
  where p(x,y)(u,v) = ((u^2)-(v^2)+x,(2*u*v)+y)

我真的不知道如何使這項工作。 任何幫助,將不勝感激!

讓我們首先忽略您的確切問題,並專注於使循環正常工作。 本質上,您想要的是具有一些初始值iv (即(0, 0) for (u, v) ),並返回列表

f iv : f (f iv) : f (f (f iv)) : f (f (f (f iv))) : ...

對於某些函數f (從您的p(x, y)構建)。 此外,您希望結果重用先前計算的列表元素。 如果我自己編寫一個執行此操作的函數,它可能看起來像這樣(但可能有一些不同的名稱):

looper :: (a -> a) -> a -> [a]
looper f iv = one_result : more_results
  where
    one_result   = f iv
    more_results = looper f one_result

但是,當然,我會首先查看是否存在具有該類型的函數。 它確實:它被稱為Data.List.iterate 它唯一做錯的是列表的第一個元素將是iv ,但這可以通過使用tail輕松修復(這里很好:只要您的迭代函數終止, iterate將始終生成一個無限列表)。


現在讓我們回到你的案例。 我們確定它通常看起來像這樣:

o :: Num a => (a, a) -> [(a, a)]
o (x, y) = tail (iterate f iv)
  where
    f (u, v) = undefined
    iv = undefined

正如您所指出的, (u, v)的初始值是(0, 0) ,這就是我們對iv的定義。 f現在必須使用o的參數中的(x, y)和該迭代的(u, v)調用p

o :: Num a => (a, a) -> [(a, a)]
o (x, y) = tail (iterate f iv)
  where
    f (u, v) = p (x, y) (u, v)
    iv = (0, 0)
    p = undefined

就這么簡單: o定義中的(x, y)實際上在where子句中的范圍內。 你甚至可以決定合並fp ,最后得到

o :: Num a => (a, a) -> [(a, a)]
o (x, y) = tail (iterate p iv)
  where
    iv = (0, 0)
    p (u, v) = (u^2 - v^2 + x, 2 * u * v + y)

另外,我可以建議您將Data.Complex用於您的應用程序嗎? 這使得在限制a有點更嚴格的(你需要RealFloat a ,因為Num.signum ),但在我看來,它使你的代碼更容易閱讀:

import Data.Complex
import Data.List (iterate)

{- ... -}

o :: Num (Complex a) => Complex a -> [Complex a]
o c = tail (iterate p iv)
  where
    iv = 0  -- or "0 :+ 0", if you want to be explicit
    p z = z^2 + c

你要:

  1. 構造一個列表[(u, v)] ,這個列表的頭部等於(0, 0)
  2. 然后使用函數\\(u, v) -> (u^2 - v^2 + x, 2 * u * v + y) map此列表,將此函數的結果附加到列表中。

我們可以像描述的那樣編寫這個函數:

func :: (Num t) => (t, t) -> [(t, t)]
func (x, y) = (0, 0) : map functionP (func (x, y))
    where functionP (u, v) = (u^2 - v^2 + x, 2 * u * v + y)

GHCi > take 5 $ func (1, 2)
     > [(0,0),(1,2),(-2,6),(-31,-22),(478,1366)]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM