Since calculation expressions can be parameterized , you can try something like this first:
let filterAndCollect (pred : 'a -> 'b -> bool) (f : 'a -> 'b list) (m : 'a list) =
let f' a = [ for b in f a do if pred a b then yield b ]
List.collect f' m
type FilteringListMonad(pred) =
member o.Bind( (m:'a list), (f: 'a -> 'b list) ) = filterAndCollect pred f m
member o.Return(x) = [x]
let filteredList = FilteringListMonad(fun x y -> x < y)
let test2 =
filteredList {
let! x = [1 .. 10]
let! y = [2 .. 2 .. 20]
return (x,y)
}
However, this fails with a type error for the tuple (x,y):
, 'int', ''a * 'b'
: y x < y FilteringListMonad :
, . 'a ''b'.
1 let! x = [1 .. 10] :
, . 'b 'int'.
, (a 'b list) int list, int * int list. , . .. , , 'b, , int * int, , 'b, :
let filterAndCollect (pred : 'b -> bool) (f : 'a -> 'b list) (m : 'a list) =
let f' a = [ for b in f a do if pred b then yield b ]
List.collect f' m
type FilteringListMonad(pred) =
member o.Bind( (m:'a list), (f: 'a -> 'b list) ) = filterAndCollect pred f m
member o.Return(x) = [x]
let filteredList = FilteringListMonad(fun (x:int,y:int) -> x < y)
let test2 =
filteredList {
let! x = [ 1 .. 10]
let! y = [2 .. 2 .. 20]
return (x,y)
}
, . F # " , System.IComparable, int s, , , ,
, 'System.IComparable', 'int'.
int .