Функция Хаскелла более высокого порядка для уменьшения

#haskell

Вопрос:

Я работаю над этой практикой тестирования кода для этого класса и столкнулся с этой проблемой, и, честно говоря, не слишком уверен, как ее решить, я думал о том, как использовать для этого foldr, но не слишком уверен, как подойти к этой проблеме. Любые рекомендации и объяснения были бы полезны, спасибо.

Напишите функцию более высокого порядка, вызываемую lreduce в Haskell, которая принимает функцию с двумя параметрами F и список [a1,a2,...,an] в качестве аргументов и создает:

 F(...F(F(a1,a2),a3)...,an)
 

Функция отклонения является :

 lreduce :: (a -> a -> a) -> [a] -> a
 

Комментарии:

1. это, по сути, foldl1

2. Звучит похоже foldl1 , но вас, вероятно, попросят реализовать его с нуля. Конечно, вы можете найти его реализацию в Интернете, но я бы счел это мошенничеством.

3. Для этого вы можете использовать рекурсию.

4. Начните с простых случаев: lreduce f [x] и lreduce f [x, y] . Это должно дать вам некоторое представление о том, как обращаться с общим случаем lreduce f (x:xs) . (Обратите внимание , что вы не можете определить lreduce f [] , поскольку единственным источником значения типа a является непустой аргумент списка.)

Ответ №1:

Я бы написал что-то вроде следующего:

 lReduce :: (a -> a -> a) -> [a] -> a
lReduce _ []        = error "Empty lists not allowed"
lReduce _ [x]       = x
lReduce f [x, x']   = f x x'
lReduce f (x:x':xs) = lReduce f (f x x' : xs)
 

Выполнение следующих действий приводит к:

 λ> lReduce (x y -> "F("    x    " "    y    ")" ) $ map show [1..10]
"F(F(F(F(F(F(F(F(F(1 2) 3) 4) 5) 6) 7) 8) 9) 10)"
 

Или аналогично

 λ> lReduce (x y -> "("    x    " `f` "    y    ")" ) $ map show [1..10]
"(((((((((1 `f` 2) `f` 3) `f` 4) `f` 5) `f` 6) `f` 7) `f` 8) `f` 9) `f` 10)"