List 列表理解中的Haskell无限递归

List 列表理解中的Haskell无限递归,list,haskell,recursion,repeat,infinite,List,Haskell,Recursion,Repeat,Infinite,我试图定义一个函数,它接受一个点(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)作为输入,并返回一个与递归调用相对应的无限列表

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)
o::numa=>(a,a)->[(a,a)]

o(x,y)=[(a,b)|(a,b)让我们先忽略你的确切问题,专注于让循环工作。本质上,你想要的是有一些东西,它需要一些初始值
iv
(即
(0,0)
,用于
(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]
活套f iv=一个结果:更多结果
哪里
一个结果=f iv
多个结果=一个结果的循环器
但是,当然,我会首先考虑是否存在这种类型的函数。它确实存在:它被调用。它唯一的错误是列表的第一个元素将是
iv
,但这可以通过使用
tail
轻松修复(这在这里很好:只要迭代函数终止,
iterate
将始终生成一个无限列表)


现在让我们回到您的案例。我们确定它通常如下所示:

o::numa=>(a,a)->[(a,a)]
o(x,y)=尾部(迭代f iv)
哪里
f(u,v)=未定义
iv=未定义
正如您所指出的,
(u,v)
的初始值是
(0,0)
,因此这就是我们对
iv
的定义。
f
现在必须使用
(x,y)
o
的参数和
(u,v)
为该迭代调用
p

o::numa=>(a,a)->[(a,a)]
o(x,y)=尾部(迭代f iv)
哪里
f(u,v)=p(x,y)(u,v)
iv=(0,0)
p=未定义
很简单:来自
o
(x,y)
的定义实际上在
where
-子句中的范围内。您甚至可以决定合并
f
p
,并以

o::numa=>(a,a)->[(a,a)]
o(x,y)=尾部(迭代p iv)
哪里
iv=(0,0)
p(u,v)=(u^2-v^2+x,2*u*v+y)

另外,我可以建议您在应用程序中使用
Data.Complex
?这使得
a
的限制更加严格(因为
Num.signum
,您需要
realfoat a
),但在我看来,它使您的代码更易于阅读:

导入数据。复杂
导入数据列表(迭代)
{- ... -}
o::Num(复数a)=>复数a->[复数a]
o c=尾部(迭代p iv)
哪里
iv=0——或者“0:+0”,如果您希望明确的话
pz=z^2+c

首先让我们忽略您的确切问题,集中精力让循环工作。本质上,您想要的是具有一些初始值
iv
(即
(u,v)
)的
(0,0)
),并返回列表

f-iv:f(f-iv):f(f(f-iv)):f(f(f(f-iv)):。。。
对于某些函数
f
(由
p
(x,y)
构造)。此外,您希望结果重用列表中以前计算的元素。如果我自己编写一个函数来执行此操作,它可能看起来像这样(但可能有一些不同的名称):

looper::(a->a)->a->[a]
活套f iv=一个结果:更多结果
哪里
一个结果=f iv
多个结果=一个结果的循环器
但是,当然,我会首先考虑是否存在这种类型的函数。它确实存在:它被调用。它唯一的错误是列表的第一个元素将是
iv
,但这可以通过使用
tail
轻松修复(这在这里很好:只要迭代函数终止,
iterate
将始终生成一个无限列表)


现在让我们回到您的案例。我们确定它通常如下所示:

o::numa=>(a,a)->[(a,a)]
o(x,y)=尾部(迭代f iv)
哪里
f(u,v)=未定义
iv=未定义
正如您所指出的,
(u,v)
的初始值是
(0,0)
,因此这就是我们对
iv
的定义。
f
现在必须使用
(x,y)
o
的参数和
(u,v)
为该迭代调用
p

o::numa=>(a,a)->[(a,a)]
o(x,y)=尾部(迭代f iv)
哪里
f(u,v)=p(x,y)(u,v)
iv=(0,0)
p=未定义
很简单:来自
o
(x,y)
的定义实际上在
where
-子句中的范围内。您甚至可以决定合并
f
p
,并以

o::numa=>(a,a)->[(a,a)]
o(x,y)=尾部(迭代p iv)
哪里
iv=(0,0)
p(u,v)=(u^2-v^2+x,2*u*v+y)

另外,我可以建议您在应用程序中使用
Data.Complex
?这使得
a
的限制更加严格(因为
Num.signum
,您需要
realfoat a
),但在我看来,它使您的代码更易于阅读:

导入数据。复杂
导入数据列表(迭代)
{- ... -
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)]