From a5d96b21859bcb8d13cb439ed65f87407886e44a Mon Sep 17 00:00:00 2001 From: Bronson Bata Date: Sat, 21 Dec 2024 12:51:16 -0600 Subject: [PATCH] [v5] Comment Cleanup (#289) * Removed commented out code from legacy v4 functions * Reverted changes to CancellableTaskOption since it isn't implemented yet --------- Co-authored-by: Jimmy Byrd --- .../CancellableTaskResultBuilderBase.fs | 208 --------------- .../CancellableTaskResultCE.fs | 95 ------- .../CancellableTaskValidationCE.fs | 251 +----------------- 3 files changed, 1 insertion(+), 553 deletions(-) diff --git a/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskResultBuilderBase.fs b/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskResultBuilderBase.fs index 9d9f6024..196aaf78 100644 --- a/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskResultBuilderBase.fs +++ b/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskResultBuilderBase.fs @@ -697,15 +697,6 @@ module CancellableTaskResultBuilderBase = continuation = (fun v -> this.Return v) ) - - // [] - // member inline this.BindReturn - // ( - // [] getAwaiterT: CancellationToken -> 'Awaiter, - // mapper: 'TResult1 -> 'TResult2 - // ) : CancellableTaskResultBuilderBaseCode<_, _, _, _> = - // this.Bind((fun ct -> getAwaiterT ct), (fun v -> this.Return(mapper v))) - /// /// The entry point for the dynamic implementation of the corresponding operation. Do not use directly, only used when executing quotations that involve tasks or other reflective execution of F# code. /// @@ -828,124 +819,12 @@ module CancellableTaskResultBuilderBase = : CancellableTaskResultBuilderBaseCode<_, _, _, 'Builder> = this.Bind(awaiterT = awaiterT, continuation = (fun v -> this.Return v)) - // [] - // member inline this.BindReturn - // ( - // awaiterT: 'Awaiter, - // [] mapper: 'a -> 'TResult2 - // ) : CancellableTaskResultBuilderBaseCode<'TResult2, 'TResult2, 'Error, 'Builder> = - // this.Bind(awaiterT = awaiterT, continuation = (fun v -> this.Return(mapper v))) - - /// [] module LowPriority = // Low priority extensions type CancellableTaskResultBuilderBase with - // /// - // /// The entry point for the dynamic implementation of the corresponding operation. Do not use directly, only used when executing quotations that involve tasks or other reflective execution of F# code. - // /// - // [] - // static member inline BindDynamic - // ( - // sm: - // byref>>, - // [] getAwaiter: CancellationToken -> 'Awaiter, - // continuation: - // ('TResult1 - // -> CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder>) - // ) : bool = - // sm.Data.ThrowIfCancellationRequested() - - // let mutable awaiter = getAwaiter sm.Data.CancellationToken - - // let cont = - // (CancellableTaskResultBuilderBaseResumptionFunc<'TOverall, 'Error, _>(fun sm -> - // let result = Awaiter.GetResult awaiter - - // match result with - // | Ok result -> (continuation result).Invoke(&sm) - // | Error e -> - // sm.Data.Result <- Error e - // true - // )) - - // // shortcut to continue immediately - // if Awaiter.IsCompleted awaiter then - // cont.Invoke(&sm) - // else - // sm.ResumptionDynamicInfo.ResumptionData <- - // (awaiter :> ICriticalNotifyCompletion) - - // sm.ResumptionDynamicInfo.ResumptionFunc <- cont - // false - - // /// Creates A CancellableTask that runs computation, and when - // /// computation generates a result T, runs binder res. - // /// - // /// A cancellation check is performed when the computation is executed. - // /// - // /// The existence of this method permits the use of let! in the - // /// cancellableTask { ... } computation expression syntax. - // /// - // /// The computation to provide an unbound result. - // /// The function to bind the result of computation. - // /// - // /// A CancellableTask that performs a monadic bind on the result - // /// of computation. - // [] - // member inline _.Bind - // ( - // [] getAwaiterTResult: CancellationToken -> 'Awaiter, - // continuation: - // ('TResult1 - // -> CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder>) - // ) : CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder> = - - // CancellableTaskResultBuilderBaseCode<'TOverall, 'TResult2, 'Error, 'Builder>(fun sm -> - // if __useResumableCode then - // //-- RESUMABLE CODE START - // sm.Data.ThrowIfCancellationRequested() - // // Get an awaiter from the Awaiter - // let mutable awaiter = getAwaiterTResult sm.Data.CancellationToken - - // let mutable __stack_fin = true - - // if not (Awaiter.IsCompleted awaiter) then - // // This will yield with __stack_yield_fin = false - // // This will resume with __stack_yield_fin = true - // let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm) - // __stack_fin <- __stack_yield_fin - - // if __stack_fin then - // let result = Awaiter.GetResult awaiter - - // match result with - // | Ok result -> (continuation result).Invoke(&sm) - // | Error e -> - // sm.Data.Result <- Error e - // true - // else - // let mutable awaiter = awaiter :> ICriticalNotifyCompletion - - // MethodBuilder.AwaitUnsafeOnCompleted( - // &sm.Data.MethodBuilder, - // &awaiter, - // &sm - // ) - - // false - // else - // CancellableTaskResultBuilderBase.BindDynamic( - // &sm, - // getAwaiterTResult, - // continuation - // ) - // //-- RESUMABLE CODE END - // ) - - /// Delegates to the input computation. /// /// The existence of this method permits the use of return! in the @@ -963,16 +842,6 @@ module CancellableTaskResultBuilderBase = continuation = (fun v -> this.Return v) ) - - // [] - // member inline this.BindReturn - // ( - // [] getAwaiterTResult: CancellationToken -> 'Awaiter, - // mapper: 'TResult1 -> 'TResult2 - // ) : CancellableTaskResultBuilderBaseCode<_, _, _, _> = - // this.Bind((fun ct -> getAwaiterTResult ct), (fun v -> this.Return(mapper v))) - - /// Allows the computation expression to turn other types into CancellationToken -> 'Awaiter /// /// This turns a CancellationToken -> 'Awaitable into a CancellationToken -> 'Awaiter. @@ -1145,18 +1014,6 @@ module CancellableTaskResultBuilderBase = : CancellableTaskResultBuilderBaseCode<_, _, _, 'Builder> = this.Bind(awaiterTResult = awaiterTResult, continuation = (fun v -> this.Return v)) - // [] - // member inline this.BindReturn - // ( - // awaiterTResult: 'Awaiter, - // [] mapper: 'a -> 'TResult2 - // ) : CancellableTaskResultBuilderBaseCode<'TResult2, 'TResult2, 'Error, 'Builder> = - // this.Bind( - // awaiterTResult = awaiterTResult, - // continuation = (fun v -> this.Return(mapper v)) - // ) - - /// Allows the computation expression to turn other types into CancellationToken -> 'Awaiter /// /// This is the identify function. @@ -1298,71 +1155,6 @@ module CancellableTaskResultBuilderBase = : Async<_> = Async.AwaitCancellableTaskResult t - - // type AsyncEx with - - // /// Return an asynchronous computation that will wait for the given task to complete and return - // /// its result. - // /// - // /// - // /// This is based on Async.Await overload (esp. AwaitTask without throwing AggregateException) - // /// - // static member inline AwaitCancellableTask - // ([] t: CancellationToken -> Task<'T>) - // = - // asyncEx { - // let! ct = Async.CancellationToken - // return! t ct - // } - - // /// Return an asynchronous computation that will wait for the given task to complete and return - // /// its result. - // /// - // /// - // /// This is based on Async.Await overload (esp. AwaitTask without throwing AggregateException) - // /// - // static member inline AwaitCancellableTask - // ([] t: CancellationToken -> Task) - // = - // asyncEx { - // let! ct = Async.CancellationToken - // return! t ct - // } - - // type Microsoft.FSharp.Control.Async with - - // /// Return an asynchronous computation that will wait for the given task to complete and return - // /// its result. - // static member inline AwaitCancellableTask - // ([] t: CancellationToken -> Task<'T>) - // = - // async { - // let! ct = Async.CancellationToken - - // return! - // t ct - // |> Async.AwaitTask - // } - - // /// Return an asynchronous computation that will wait for the given task to complete and return - // /// its result. - // static member inline AwaitCancellableTask - // ([] t: CancellationToken -> Task) - // = - // async { - // let! ct = Async.CancellationToken - - // return! - // t ct - // |> Async.AwaitTask - // } - - // /// Runs an asynchronous computation, starting on the current operating system thread. - // static member inline AsCancellableTask - // (computation: Async<'T>) - // : CancellationToken -> Task<_> = - // fun ct -> Async.StartImmediateAsTask(computation, cancellationToken = ct) - // High priority extensions type CancellableTaskResultBuilderBase with diff --git a/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskResultCE.fs b/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskResultCE.fs index d3571b7c..77079a54 100644 --- a/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskResultCE.fs +++ b/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskResultCE.fs @@ -142,58 +142,6 @@ module CancellableTaskResultCE = : CancellationToken -> Awaiter, _> = fun ct -> Awaitable.GetTaskAwaiter(x ct) - // member inline this.MergeSources - // ( - // [] left: CancellationToken -> 'Awaiter1, - // [] right: CancellationToken -> 'Awaiter2 - // ) = - // this.Run( - // this.Bind( - // left, - // fun leftR -> this.BindReturn(right, (fun rightR -> struct (leftR, rightR))) - // ) - // ) - // >> Awaitable.GetTaskAwaiter - - - // member inline this.MergeSources - // ( - // left: 'Awaiter1, - // [] right: CancellationToken -> 'Awaiter2 - // ) = - // this.Run( - // this.Bind( - // left, - // fun leftR -> this.BindReturn(right, (fun rightR -> struct (leftR, rightR))) - // ) - // ) - // >> Awaitable.GetTaskAwaiter - - - // member inline this.MergeSources - // ( - // [] left: CancellationToken -> 'Awaiter1, - // right: 'Awaiter2 - // ) = - // this.Run( - // this.Bind( - // left, - // fun leftR -> this.BindReturn(right, (fun rightR -> struct (leftR, rightR))) - // ) - // ) - // >> Awaitable.GetTaskAwaiter - - - // member inline this.MergeSources(left: 'Awaiter1, right: 'Awaiter2) = - // this.Run( - // this.Bind( - // left, - // fun leftR -> this.BindReturn(right, (fun rightR -> struct (leftR, rightR))) - // ) - // ) - // >> Awaitable.GetTaskAwaiter - - /// Contains methods to build CancellableTasks using the F# computation expression syntax type BackgroundCancellableTaskResultBuilder() = @@ -312,49 +260,6 @@ module CancellableTaskResultCE = let backgroundCancellableTaskResult = BackgroundCancellableTaskResultBuilder() -// /// -// /// A set of extension methods making it possible to bind against in async computations. -// /// -// [] -// module AsyncExtensions = - -// type AsyncExBuilder with - -// member inline this.Source([] t: CancellableTask<'T>) : Async<'T> = -// AsyncEx.AwaitCancellableTask t - -// member inline this.Source([] t: CancellableTask) : Async = -// AsyncEx.AwaitCancellableTask t - -// type Microsoft.FSharp.Control.AsyncBuilder with - -// member inline this.Bind -// ( -// [] t: CancellableTask<'T>, -// [] binder: ('T -> Async<'U>) -// ) : Async<'U> = -// this.Bind(Async.AwaitCancellableTask t, binder) - -// member inline this.ReturnFrom([] t: CancellableTask<'T>) : Async<'T> = -// this.ReturnFrom(Async.AwaitCancellableTask t) - -// member inline this.Bind -// ( -// [] t: CancellableTask, -// [] binder: (unit -> Async<'U>) -// ) : Async<'U> = -// this.Bind(Async.AwaitCancellableTask t, binder) - -// member inline this.ReturnFrom([] t: CancellableTask) : Async = -// this.ReturnFrom(Async.AwaitCancellableTask t) - -// // There is explicitly no Binds for `CancellableTasks` in `Microsoft.FSharp.Control.TaskBuilderBase`. -// // You need to explicitly pass in a `CancellationToken`to start it, you can use `CancellationToken.None`. -// // Reason is I don't want people to assume cancellation is happening without the caller being explicit about where the CancellationToken came from. -// // Similar reasoning for `IcedTasks.ColdTasks.ColdTaskBuilderBase`. - -// // Contains a set of standard functional helper function - [] module CancellableTaskResult = open System.Threading.Tasks diff --git a/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskValidationCE.fs b/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskValidationCE.fs index 0e0fd54d..32f9061c 100644 --- a/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskValidationCE.fs +++ b/src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskValidationCE.fs @@ -549,23 +549,6 @@ module CTVMergeSourcesExtensionsCT1CT2 = [] right: CancellationToken -> 'Awaiter2 ) = this.Source( - // cancellableTask.Run( - // cancellableTask.Bind( - // (fun ct -> cancellableTask.Source(ValueTask<_> ct)), - // fun ct -> - // let left = left ct - // let right = right ct - - // (cancellableTask.Bind( - // left, - // fun leftR -> - // cancellableTask.BindReturn( - // right, - // (fun rightR -> Validation.zip (Ok leftR) (Ok rightR)) - // ) - // )) - // ) - // ) cancellableTask { let! struct (l1, r1) = cancellableTask.MergeSources(left, right) return Validation.zip (Ok l1) (Ok r1) @@ -584,23 +567,6 @@ module CTVMergeSourcesExtensionsCV1CT2 = [] right: CancellationToken -> 'Awaiter2 ) = this.Source( - // cancellableTask.Run( - // cancellableTask.Bind( - // (fun ct -> cancellableTask.Source(ValueTask<_> ct)), - // fun ct -> - // let left = left ct - // let right = right ct - - // (cancellableTask.Bind( - // left, - // fun leftR -> - // cancellableTask.BindReturn( - // right, - // (fun rightR -> Validation.zip leftR (Ok rightR)) - // ) - // )) - // ) - // ) cancellableTask { let! struct (l1, r1) = cancellableTask.MergeSources(left, right) return Validation.zip l1 (Ok r1) @@ -620,23 +586,6 @@ module CTVMergeSourcesExtensionsCT1CV2 = [] right: CancellationToken -> 'Awaiter2 ) = this.Source( - // cancellableTask.Run( - // cancellableTask.Bind( - // (fun ct -> cancellableTask.Source(ValueTask<_> ct)), - // fun ct -> - // let left = left ct - // let right = right ct - - // (cancellableTask.Bind( - // left, - // fun leftR -> - // cancellableTask.BindReturn( - // right, - // (fun rightR -> Validation.zip (Ok leftR) rightR) - // ) - // )) - // ) - // ) cancellableTask { let! struct (l1, r1) = cancellableTask.MergeSources(left, right) return Validation.zip (Ok l1) r1 @@ -656,23 +605,6 @@ module CTVMergeSourcesExtensionsCV1CV2 = [] right: CancellationToken -> 'Awaiter2 ) = this.Source( - // cancellableTask.Run( - // cancellableTask.Bind( - // (fun ct -> cancellableTask.Source(ValueTask<_> ct)), - // fun ct -> - // let left = left ct - // let right = right ct - - // (cancellableTask.Bind( - // left, - // fun leftR -> - // cancellableTask.BindReturn( - // right, - // (fun rightR -> Validation.zip leftR rightR) - // ) - // )) - // ) - // ) cancellableTask { let! struct (l1, r1) = cancellableTask.MergeSources(left, right) return Validation.zip l1 r1 @@ -690,22 +622,6 @@ module CTVMergeSourcesExtensionsCT1T2 = ([] left: CancellationToken -> 'Awaiter1, right: 'Awaiter2) = this.Source( - // cancellableTask.Run( - // cancellableTask.Bind( - // (fun ct -> cancellableTask.Source(ValueTask<_> ct)), - // fun ct -> - // let left = left ct - - // (cancellableTask.Bind( - // left, - // fun leftR -> - // cancellableTask.BindReturn( - // right, - // (fun rightR -> Validation.zip (Ok leftR) (Ok rightR)) - // ) - // )) - // ) - // ) cancellableTask { let! struct (l1, r1) = cancellableTask.MergeSources(left, right) return Validation.zip (Ok l1) (Ok r1) @@ -722,22 +638,6 @@ module CTVMergeSourcesExtensionsCV1T2 = ([] left: CancellationToken -> 'Awaiter1, right: 'Awaiter2) = this.Source( - // cancellableTask.Run( - // cancellableTask.Bind( - // (fun ct -> cancellableTask.Source(ValueTask<_> ct)), - // fun ct -> - // let left = left ct - - // (cancellableTask.Bind( - // left, - // fun leftR -> - // cancellableTask.BindReturn( - // right, - // (fun rightR -> Validation.zip leftR (Ok rightR)) - // ) - // )) - // ) - // ) cancellableTask { let! struct (l1, r1) = cancellableTask.MergeSources(left, right) return Validation.zip l1 (Ok r1) @@ -755,22 +655,6 @@ module CTVMergeSourcesExtensionsCT1TV2 = ([] left: CancellationToken -> 'Awaiter1, right: 'Awaiter2) = this.Source( - // cancellableTask.Run( - // cancellableTask.Bind( - // (fun ct -> cancellableTask.Source(ValueTask<_> ct)), - // fun ct -> - // let left = left ct - - // (cancellableTask.Bind( - // left, - // fun leftR -> - // cancellableTask.BindReturn( - // right, - // (fun rightR -> Validation.zip (Ok leftR) rightR) - // ) - // )) - // ) - // ) cancellableTask { let! struct (l1, r1) = cancellableTask.MergeSources(left, right) return Validation.zip (Ok l1) r1 @@ -788,22 +672,6 @@ module CTVMergeSourcesExtensionsCV1TV2 = ([] left: CancellationToken -> 'Awaiter1, right: 'Awaiter2) = this.Source( - // cancellableTask.Run( - // cancellableTask.Bind( - // (fun ct -> cancellableTask.Source(ValueTask<_> ct)), - // fun ct -> - // let left = left ct - - // (cancellableTask.Bind( - // left, - // fun leftR -> - // cancellableTask.BindReturn( - // right, - // (fun rightR -> Validation.zip leftR (rightR)) - // ) - // )) - // ) - // ) cancellableTask { let! struct (l1, r1) = cancellableTask.MergeSources(left, right) return Validation.zip l1 r1 @@ -820,22 +688,6 @@ module CTVMergeSourcesExtensionsT1CT2 = (left: 'Awaiter1, [] right: CancellationToken -> 'Awaiter2) = this.Source( - // cancellableTask.Run( - // cancellableTask.Bind( - // (fun ct -> cancellableTask.Source(ValueTask<_> ct)), - // fun ct -> - // let right = right ct - - // (cancellableTask.Bind( - // left, - // fun leftR -> - // cancellableTask.BindReturn( - // right, - // (fun rightR -> Validation.zip (Ok leftR) (Ok rightR)) - // ) - // )) - // ) - // ) cancellableTask { let! struct (l1, r1) = cancellableTask.MergeSources(left, right) return Validation.zip (Ok l1) (Ok r1) @@ -852,22 +704,6 @@ module CTVMergeSourcesExtensionsTV1CT2 = (left: 'Awaiter1, [] right: CancellationToken -> 'Awaiter2) = this.Source( - // cancellableTask.Run( - // cancellableTask.Bind( - // (fun ct -> cancellableTask.Source(ValueTask<_> ct)), - // fun ct -> - // let right = right ct - - // (cancellableTask.Bind( - // left, - // fun leftR -> - // cancellableTask.BindReturn( - // right, - // (fun rightR -> Validation.zip leftR (Ok rightR)) - // ) - // )) - // ) - // ) cancellableTask { let! struct (l1, r1) = cancellableTask.MergeSources(left, right) return Validation.zip l1 (Ok r1) @@ -885,26 +721,10 @@ module CTVMergeSourcesExtensionsT1CV2 = (left: 'Awaiter1, [] right: CancellationToken -> 'Awaiter2) = this.Source( - // cancellableTask.Run( - // cancellableTask.Bind( - // (fun ct -> cancellableTask.Source(ValueTask<_> ct)), - // fun ct -> - // let right = right ct - - // (cancellableTask.Bind( - // left, - // fun leftR -> - // cancellableTask.BindReturn( - // right, - // (fun rightR -> Validation.zip (Ok leftR) rightR) - // ) - // )) - // ) cancellableTask { let! struct (l1, r1) = cancellableTask.MergeSources(left, right) return Validation.zip (Ok l1) r1 } - // ) ) [] @@ -917,38 +737,12 @@ module CTVMergeSourcesExtensionsTV1CV2 = member inline this.MergeSources (left: 'Awaiter1, [] right: CancellationToken -> 'Awaiter2) = + this.Source( - // cancellableTask.Run( - // cancellableTask.Bind( - // (fun ct -> cancellableTask.Source(ValueTask<_> ct)), - // fun ct -> - // let right = right ct - - // (cancellableTask.Bind( - // left, - // fun leftR -> - // cancellableTask.BindReturn( - // right, - // (fun rightR -> Validation.zip leftR rightR) - // ) - // )) - // ) - // ) cancellableTask { let! struct (l1, r1) = cancellableTask.MergeSources(left, right) return Validation.zip l1 r1 } - // fun ct -> Awaitable.GetTaskAwaiter(IcedTasks.Polyfill.Task.Tasks.TaskBuilder.task { - // let r1 = right ct - // let l1 = left - // let! struct (l1, r1) = IcedTasks.Polyfill.Task.Tasks.TaskBuilder.task.MergeSources(l1, r1) - - // // let foo = cancellableTask.MergeSources(left, right) ct - // return Validation.zip l1 r1 - // }) - // |> ignore - - // Unchecked.defaultof<_> ) @@ -960,20 +754,6 @@ module CTVMergeSourcesExtensionsT1T2 = [] member inline this.MergeSources(left: 'Awaiter1, right: 'Awaiter2) = this.Source( - // cancellableTask.Run( - // cancellableTask.Bind( - // (fun ct -> cancellableTask.Source(ValueTask<_> ct)), - // fun ct -> - // (cancellableTask.Bind( - // left, - // fun leftR -> - // cancellableTask.BindReturn( - // right, - // (fun rightR -> Validation.zip (Ok leftR) (Ok rightR)) - // ) - // )) - // ) - // ) cancellableTask { let! struct (l1, r1) = cancellableTask.MergeSources(left, right) return Validation.zip (Ok l1) (Ok r1) @@ -988,21 +768,6 @@ module CTVMergeSourcesExtensionsTV1T2 = [] member inline this.MergeSources(left: 'Awaiter1, right: 'Awaiter2) = this.Source( - // cancellableTask.Run( - // cancellableTask.Bind( - // (fun ct -> cancellableTask.Source(ValueTask<_> ct)), - // fun ct -> - - // (cancellableTask.Bind( - // left, - // fun leftR -> - // cancellableTask.BindReturn( - // right, - // (fun rightR -> Validation.zip leftR (Ok rightR)) - // ) - // )) - // ) - // ) cancellableTask { let! struct (l1, r1) = cancellableTask.MergeSources(left, right) return Validation.zip l1 (Ok r1) @@ -1018,20 +783,6 @@ module CTVMergeSourcesExtensionsT1TV2 = [] member inline this.MergeSources(left: 'Awaiter1, right: 'Awaiter2) = this.Source( - // cancellableTask.Run( - // cancellableTask.Bind( - // (fun ct -> cancellableTask.Source(ValueTask<_> ct)), - // fun ct -> - // (cancellableTask.Bind( - // left, - // fun leftR -> - // cancellableTask.BindReturn( - // right, - // (fun rightR -> Validation.zip (Ok leftR) rightR) - // ) - // )) - // ) - // ) cancellableTask { let! struct (l1, r1) = cancellableTask.MergeSources(left, right) return Validation.zip (Ok l1) r1