Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct Observable.filteri bug and optimise Observable.mapi #72

Merged
merged 6 commits into from
Jan 9, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion paket.dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ source http://nuget.org/api/v2
nuget FAKE
nuget SourceLink.Fake
nuget Nuget.CommandLine
nuget FSharp.Core ~> 3.1.2
nuget FSharp.Core ~> 4.0.0.1
nuget Rx-Experimental ~> 2.2.5
nuget Rx-Main ~> 2.2.5
nuget Rx-PlatformServices ~> 2.2.5
nuget Rx-Testing ~> 2.2.5
nuget NUnit
nuget NUnit.Runners
nuget FsCheck.NUnit
nuget FSharp.Formatting
nuget FSharp.Compiler.Service
18 changes: 12 additions & 6 deletions paket.lock
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
NUGET
remote: http://nuget.org/api/v2
remote: http://www.nuget.org/api/v2
specs:
FAKE (4.0.3)
FSharp.Compiler.Service (1.4.0.1)
FSharp.Core (3.1.2.5)
FAKE (4.12.2)
FsCheck (2.2.4)
FSharp.Core (>= 3.1.2.5)
FsCheck.Nunit (2.2.4)
FsCheck (>= 2.2.4)
NUnit (>= 2.6.4 < 2.7.0)
NUnit.Runners (>= 2.6.4 < 2.7.0)
FSharp.Compiler.Service (2.0.0.2)
FSharp.Core (4.0.0.1)
FSharp.Formatting (2.10.0)
FSharp.Compiler.Service (>= 0.0.87)
FSharpVSPowerTools.Core (1.8.0)
FSharpVSPowerTools.Core (1.8.0)
FSharp.Compiler.Service (>= 0.0.87)
NuGet.CommandLine (2.8.6)
NuGet.CommandLine (3.3.0)
NUnit (2.6.4)
NUnit.Runners (2.6.4)
Rx-Core (2.2.5)
Expand All @@ -35,4 +41,4 @@ NUGET
Rx-Main (>= 2.2.5)
Rx-Testing (2.2.5)
Rx-Main (>= 2.2.5)
SourceLink.Fake (1.0.0)
SourceLink.Fake (1.1.0)
171 changes: 59 additions & 112 deletions src/FSharp.Control.Reactive.fsproj

Large diffs are not rendered by default.

131 changes: 70 additions & 61 deletions src/FSharp.Control.Reactive/FSharp.Control.Reactive.fsproj

Large diffs are not rendered by default.

9 changes: 2 additions & 7 deletions src/Observable.fs
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ module Observable =
/// Filters the observable elements of a sequence based on a predicate by
/// incorporating the element's index
let filteri predicate (source: IObservable<'T>) =
Observable.Where( source, Func<_,_> predicate )
Observable.Where( source, Func<_,_,_> (fun i x -> predicate x i) )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should have a test or something for this...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and great catch!



/// Invokes a specified action after the source observable sequence
Expand Down Expand Up @@ -1028,12 +1028,7 @@ module Observable =
/// Maps the given observable with the given function and the
/// index of the element
let mapi (f:int -> 'Source -> 'Result) (source:IObservable<'Source>) =
source
|> Observable.scan ( fun (i,_) x -> (i+1,Some(x))) (-1,None)
|> Observable.map
( function
| i, Some(x) -> f i x
| _, None -> invalidOp "Invalid state" )
Observable.Select (source, Func<_,_,_> (fun i x -> f x i))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow; I wish I had seen that earlier. Thank you!



/// Maps two observables to the specified function.
Expand Down
216 changes: 113 additions & 103 deletions tests/FSharp.Control.Reactive.Tests.fsproj

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions tests/FsCheckAddin.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace FsCheck.NUnit.Examples

open NUnit.Core.Extensibility

open FsCheck.NUnit
open FsCheck.NUnit.Addin

[<NUnitAddin(Description = "FsCheck addin")>]
type FsCheckAddin() =
interface IAddin with
override x.Install host =
let tcBuilder = new FsCheckTestCaseBuilder()
host.GetExtensionPoint("TestCaseBuilders").Install(tcBuilder)
true

33 changes: 32 additions & 1 deletion tests/ObservableSpecs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ open System.Reactive.Linq
open FSharp.Control.Reactive
open Builders
open NUnit.Framework
open FsCheck.NUnit
open Microsoft.Reactive.Testing
open System.Reactive.Subjects
open System.Reactive.Concurrency
Expand Down Expand Up @@ -550,4 +551,34 @@ let ``FlatMapAsync should take F# async workflows and flatmap them to observable
Assert.That(result.Count, Is.EqualTo 3)
Assert.That(result.[0], Is.EqualTo expected)
Assert.That(result.[1], Is.EqualTo expected)
Assert.That(result.[2], Is.EqualTo expected)
Assert.That(result.[2], Is.EqualTo expected)

[<Property>]
let ``Observable.mapi should be equivalent to Array.mapi`` (items : int array) =
items
|> Observable.ofSeq
|> Observable.mapi (fun i x -> (i, x))
|> Observable.toEnumerable
|> Seq.toArray
|> (=) (items |> Array.mapi (fun i x -> (i, x)))

[<Property>]
let ``filteri should be equivalent to mapi then filter`` (items : int array) =
let predicate i x = (i % 2 = 0) && (x > 0)

let filtered =
items
|> Observable.ofSeq
|> Observable.mapi (fun i x -> (i, x))
|> Observable.filter (fun (i, x) -> predicate i x)
|> Observable.map snd
|> Observable.toEnumerable
|> Seq.toArray

let filtered' =
Observable.ofSeq items
|> Observable.filteri predicate
|> Observable.toEnumerable
|> Seq.toArray

filtered = filtered'
1 change: 1 addition & 0 deletions tests/paket.references
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
FSharp.Core
NUnit
NUnit.Runners
FsCheck.NUnit
Rx-Core
Rx-Experimental
Rx-Interfaces
Expand Down