#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)"