[英]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
子句中的范围内。 你甚至可以决定合并f
和p
,最后得到
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
你要:
[(u, v)]
,这个列表的头部等于(0, 0)
\\(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.