|
|
module ChurchFold
|
|
|
|
|
|
open System
|
|
|
|
|
|
|
|
|
let nil (c:'a->'b->'b) (n:'b) : 'b = n
|
|
|
|
|
|
let cons (x:'a) (xs:('a->'b->'b)->'b->'b) : ('a->'b->'b)->'b->'b =
|
|
|
fun c n -> c x (xs c n)
|
|
|
|
|
|
|
|
|
let toList (xs:('a->'b->'b)->'b->'b) : 'a list =
|
|
|
xs (fun x acc -> x :: acc) []
|
|
|
|
|
|
|
|
|
let ofList (ls:'a list) : (('a->'b->'b)->'b->'b) =
|
|
|
List.foldBack (fun x acc -> cons x acc) ls nil
|
|
|
|
|
|
|
|
|
let foldWithPredicate (churchList:(int->int list->int list)->int list->int list) (f:int->int->int) (p:int->bool) (acc:int) : int =
|
|
|
|
|
|
let regularList = toList churchList
|
|
|
|
|
|
|
|
|
let rec foldTailRec lst accumulator =
|
|
|
match lst with
|
|
|
| [] -> accumulator
|
|
|
| head :: tail ->
|
|
|
if p head then
|
|
|
|
|
|
foldTailRec tail (f accumulator head)
|
|
|
else
|
|
|
|
|
|
foldTailRec tail accumulator
|
|
|
|
|
|
foldTailRec regularList acc
|
|
|
|
|
|
[<EntryPoint>]
|
|
|
let main _ =
|
|
|
|
|
|
let numbers = ofList [1; 2; 3; 4; 5]
|
|
|
|
|
|
|
|
|
let add x y = x + y
|
|
|
|
|
|
|
|
|
let isEven x = x % 2 = 0
|
|
|
|
|
|
|
|
|
let greaterThan2 x = x > 2
|
|
|
|
|
|
printfn "Исходный список: [1; 2; 3; 4; 5]"
|
|
|
printfn ""
|
|
|
|
|
|
|
|
|
let sumEven = foldWithPredicate numbers add isEven 0
|
|
|
printfn "Сумма четных чисел (предикат isEven): %d" sumEven
|
|
|
|
|
|
|
|
|
let sumGreater2 = foldWithPredicate numbers add greaterThan2 0
|
|
|
printfn "Сумма чисел больше 2 (предикат > 2): %d" sumGreater2
|
|
|
|
|
|
|
|
|
let multiply x y = x * y
|
|
|
let productEven = foldWithPredicate numbers multiply isEven 1
|
|
|
printfn "Произведение четных чисел: %d" productEven
|
|
|
|
|
|
printfn ""
|
|
|
printfn "Демонстрация работы с различными предикатами:"
|
|
|
|
|
|
|
|
|
let isOdd x = x % 2 = 1
|
|
|
let sumOdd = foldWithPredicate numbers add isOdd 0
|
|
|
printfn "Сумма нечетных чисел: %d" sumOdd
|
|
|
|
|
|
let isPositive x = x > 0
|
|
|
let countPositive = foldWithPredicate numbers (fun acc _ -> acc + 1) isPositive 0
|
|
|
printfn "Количество положительных чисел: %d" countPositive
|
|
|
|
|
|
0 |