2016-10-01 2 views
1

Я пытаюсь определить функцию, которая принимает точку (х, у) в качестве входных данных и возвращает бесконечный список, соответствующий рекурсивного вызоваHaskell бесконечной рекурсии в списке понимание

P = (и^2 - V^2 + х, 2UV + у)

начальные значения и и V оба 0.

  • Первый вызов будет

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

Я действительно не уверен, как это сделать. Любая помощь будет оценена!

+4

[ 'итерационный P (0, 0)'] (http://hackage.haskell.org/package/base-4.9.0.0 /docs/Prelude.html#v:iterate)? – Bergi

+2

Пожалуйста, не удаляйте свой примерный код. Все начинаются где-то. Не нужно стыдиться этого :) –

+0

@Rhymoid, вы предлагаете мой код начальной школы, код BASIC и Turbo Pascal, возможно, оставили желать лучшего? Я сам когда-либо писал идеальный код, и я ожидаю того же самого от всех остальных. Программирование - серьезный бизнес, и нет никаких ошибок! – dfeuer

ответ

8

Давайте сначала проигнорируем точный вопрос, который у вас есть, и сосредоточьтесь на получении цикла. То, что вы хотите, по сути, это есть то, что занимает некоторое начальное значение iv (а именно, (0, 0) для (u, v)), и возвращает список

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

для некоторой функции f (построен из ваших p и (x, y)). Кроме того, вы хотите, чтобы результат повторно использовал ранее вычисленные элементы списка. Если бы я написать функцию себе, что делает это, он может lõoke как это (но, возможно, с некоторыми другими названиями):

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

Но, конечно, я бы первый look если функция этого типа существует. Он делает это: 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 теперь называть p с (x, y) из o «аргумента s и (u, v) для этой итерации:

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 

Это так просто, как то: (x, y) из o» определение s фактически в объеме в where -clause , Можно даже принять решение о слиянии 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 
+0

Большое вам спасибо! Это имеет большой смысл! –

0

Вы хотите:

  1. Для составить список [(u, v)] с указанием главы этого списка (0, 0)
  2. И вот map этот список с функцией \(u, v) -> (u^2 - v^2 + x, 2 * u * v + y), прилагая к нему результаты этой функции.

Мы можем написать эту функцию, как описано:

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)] 
+0

Вы уверены, что это работает так же эффективно, как решение на основе 'iterate'? –

Смежные вопросы