Итак, у меня есть тип списка:
type ConsList<'value> =
| Cons of head: 'value * tail: ConsList<'value>
| Empty
И функция раздела для него:
let rec partition lst pivot =
match lst with
| Empty -> Empty, Empty
| Cons(hd, tl) ->
let parts = partition tl pivot
if hd < pivot then
Cons(hd, fst parts), snd parts
else
fst parts, Cons(hd, snd parts)
Но мне нужно сделать функцию, которая принимает предикат и по нему распределяет элементы в первый или второй список. Например, partition (fun elem -> elem % 2 = 0) lst
Я закончил с этим:
let rec partition predicate lst =
match lst with
| Empty -> Empty, Empty
| Cons(hd, tl) ->
let parts = partition predicate tl
match predicate with
| true -> Cons(hd, fst parts), snd parts
| false -> fst parts, Cons(hd, snd parts)
Но когда вы пытаетесь дать ему лямбда-выражение, оно терпит неудачу с
[FS0002] This function takes too many arguments, or is used in a context where a function is not expected
Я думаю, вы просто забыли использовать hd
в качестве аргумента predicate
. Попробуй это:
let rec partition predicate lst =
match lst with
| Empty -> Empty, Empty
| Cons(hd, tl) ->
let parts = partition predicate tl
match predicate hd with // <- this is the line I changed
| true -> Cons(hd, fst parts), snd parts
| false -> fst parts, Cons(hd, snd parts)
Кстати, сопоставление с логическим значением — это излишество. Просто используйте if
вместо этого:
if predicate hd then
Cons(hd, fst parts), snd parts
else
fst parts, Cons(hd, snd parts)
Прецедент:
let lst = Cons (2, Cons(1, Cons (0, Empty)))
let evens, odds =
partition (fun elem -> elem % 2 = 0) lst
printfn "%A" evens // Cons (2, Cons (0, Empty))
printfn "%A" odds // Cons (1, Empty)