Как реализовать вложенные функции в haskell



Недавно я столкнулся с этим вопросом:



, который в основном спрашивает, как реализовать эту функцию для вычисления предела f (n):



Введите описание изображения здесь



Как бы я реализовал это в haskell? Я пытаюсь научиться функциональному программированию, и это кажется мне сейчас хорошей задачей

564   1  

1 ответ:

Есть куча способов!

Вот один, использующий рекурсивную вспомогательную функцию:

f :: (Eq a, Floating a) => a -> a
f n = f' n n
  where f' 1 x = x
        f' n x = let n' = n-1 in f' n' (n' / (1 + x))

Разработка его вручную:

f 1 = f' 1 1 
    = 1
f 2 = f' 2 2 
    = f' 1 (1 / (1 + 2)) 
    = 1/(1+2)
f 3 = f' 3 3 
    = f' 2 (2 / (1 + 3))
    = f' 1 (1 / (1 + (2 / (1 + 3))))
    = 1 / (1 + (2 / (1 + 3)))

Вот другой способ сделать это с помощью рекурсивной вспомогательной функции:

f :: (Eq a, Floating a) => a -> a
f n = f' 1 n
  where f' a n | a == n    = a
               | otherwise = a / (1 + f' (a+1) n)

Разработка его вручную:

f 1 = f' 1 1 
    = 1
f 2 = f' 1 2 
    = 1 / (1 + f' 2 2) 
    = 1 / (1 + 2)
f 3 = f' 1 3 
    = 1 / (1 + f' 2 3)
    = 1 / (1 + (2 / (1 + f' 3 3)))
    = 1 / (1 + (2 / (1 + 3)))
Первый подход был хвост-рекурсивным, в то время как второй был просто рекурсивным.

Или, как говорится в ссылке, складкой

f :: (Eq a, Floating a) => a -> a
f n = foldr1 (\n x -> n / (1 + x)) [1..n]

Опять же, работая вручную:

f 5 = foldr1 (\n x -> n / (1 + x)) [1,2,3,4,5]
    = g 1 (g 2 (g 3 (g 4 5)))
    = g 1 (g 2 (g 3 (4 / (1 + 5))))
    = g 1 (g 2 (3 / (1 + (4 / (1 + 5)))))
    = g 1 (2 / ( 1 + (3 / (1 + (4 / (1 + 5))))))
    = 1 / (1 + (2 / ( 1 + (3 / (1 + (4 / (1 + 5)))))))
  where g = \n x -> n / (1 + x)

Comments

    Ничего не найдено.