|
|
|
@ -0,0 +1,64 @@
|
|
|
|
|
type ChurchList<'a> = ('a -> 'b -> 'b) -> 'b -> 'b
|
|
|
|
|
|
|
|
|
|
let nil : ChurchList<'a> = fun _ z -> z
|
|
|
|
|
|
|
|
|
|
let cons (x: 'a) (xs: ChurchList<'a>) : ChurchList<'a> =
|
|
|
|
|
fun f z -> f x (xs f z)
|
|
|
|
|
|
|
|
|
|
let toList (churchList: ChurchList<'a>) : 'a list =
|
|
|
|
|
churchList (fun x acc -> x :: acc) []
|
|
|
|
|
|> List.rev
|
|
|
|
|
|
|
|
|
|
let ofList (lst: 'a list) : ChurchList<'a> =
|
|
|
|
|
List.foldBack cons lst nil
|
|
|
|
|
|
|
|
|
|
let foldWithPredicate (f: 'a -> 'b -> 'b) (p: 'a -> bool) (acc: 'b) (churchList: ChurchList<'a>) : 'b =
|
|
|
|
|
let rec foldTailRec lst currentAcc =
|
|
|
|
|
match lst with
|
|
|
|
|
| [] -> currentAcc
|
|
|
|
|
| x :: xs ->
|
|
|
|
|
if p x then
|
|
|
|
|
foldTailRec xs (f x currentAcc)
|
|
|
|
|
else
|
|
|
|
|
foldTailRec xs currentAcc
|
|
|
|
|
|
|
|
|
|
let regularList = toList churchList
|
|
|
|
|
foldTailRec regularList acc
|
|
|
|
|
|
|
|
|
|
let findMin (churchList: ChurchList<int>) : int option =
|
|
|
|
|
let regularList = toList churchList
|
|
|
|
|
match regularList with
|
|
|
|
|
| [] -> None
|
|
|
|
|
| x :: xs ->
|
|
|
|
|
let minValue = foldWithPredicate (fun x acc -> min x acc) (fun _ -> true) x churchList
|
|
|
|
|
Some minValue
|
|
|
|
|
|
|
|
|
|
let sumEven (churchList: ChurchList<int>) : int =
|
|
|
|
|
foldWithPredicate (+) (fun x -> x % 2 = 0) 0 churchList
|
|
|
|
|
|
|
|
|
|
let countOdd (churchList: ChurchList<int>) : int =
|
|
|
|
|
foldWithPredicate (fun _ acc -> acc + 1) (fun x -> x % 2 <> 0) 0 churchList
|
|
|
|
|
|
|
|
|
|
[<EntryPoint>]
|
|
|
|
|
let main argv =
|
|
|
|
|
let testList = ofList [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
|
|
|
|
|
let emptyList = nil
|
|
|
|
|
|
|
|
|
|
printfn "Тестовый список: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]"
|
|
|
|
|
|
|
|
|
|
match findMin testList with
|
|
|
|
|
| Some min -> printfn "Минимальный элемент: %d" min
|
|
|
|
|
| None -> printfn "Список пуст"
|
|
|
|
|
|
|
|
|
|
printfn "Сумма четных чисел: %d" (sumEven testList)
|
|
|
|
|
printfn "Количество нечетных чисел: %d" (countOdd testList)
|
|
|
|
|
|
|
|
|
|
printfn "\nТест с пустым списком:"
|
|
|
|
|
match findMin emptyList with
|
|
|
|
|
| Some min -> printfn "Минимальный элемент: %d" min
|
|
|
|
|
| None -> printfn "Список пуст"
|
|
|
|
|
|
|
|
|
|
printfn "Сумма четных чисел в пустом списке: %d" (sumEven emptyList)
|
|
|
|
|
printfn "Количество нечетных чисел в пустом списке: %d" (countOdd emptyList)
|
|
|
|
|
|
|
|
|
|
0
|