Совпадение шаблонов для лямбда-выражений

 21 --Primitive recursion constructor
 22 pr :: ([Int] -> Int) -> ([Int] -> Int) -> ([Int] -> Int)
 23 pr f g = \xs 0 -> f xs
 24 pr f g = \xs (y+1) -> g xs y ((pr f g) xs y)

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

Спасибо

Ответ 1

pr f g = \xs y' -> case y' of 0     -> f xs
                              (y+1) -> g xs y ((pr f g) xs y)

или просто

pr f g xs 0 = f xs
pr f g xs (y+1) = g xs y ((pr f g) xs y)

(Помните, что f a b = ... является в основном ярлыком для f a = \b -> ..., который является ярлыком для f = \a -> \b -> ....)

Обратите внимание, что n + 1 шаблонов устарели и что тип, указанный вами для pr, не соответствует вашему (и моему) определению.

В зависимости от вашего типа функция принимает [Int] -> Int (f), затем функцию, которая принимает еще один [Int] -> Int (g), затем функцию, которая принимает [Int] (xs), а затем возвращает Int. Однако вы вызываете g с тремя аргументами, а последняя возвращаемая функция принимает два аргумента, поэтому предположительно вы хотите что-то вроде ([Int] -> Int) -> ([Int] -> Int -> Int -> Int) -> [Int] -> Int -> Int.