-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,6 +30,29 @@ let ``append is consistent`` () = | |
Check.QuickThrowOnFailure append<string> | ||
Check.QuickThrowOnFailure append<NormalFloat> | ||
|
||
let averageFloat (xs : NormalFloat []) = | ||
let xs = xs |> Array.map float | ||
let s = run (fun () -> xs |> Seq.average) | ||
let l = run (fun () -> xs |> List.ofArray |> List.average) | ||
let a = run (fun () -> xs |> Array.average) | ||
s = a && l = a | ||
|
||
[<Test>] | ||
let ``average is consistent`` () = | ||
Check.QuickThrowOnFailure averageFloat | ||
|
||
let averageBy (xs : float []) f = | ||
This comment has been minimized.
Sorry, something went wrong. |
||
let xs = xs |> Array.map float | ||
let f x = (f x : NormalFloat) |> float | ||
let s = run (fun () -> xs |> Seq.averageBy f) | ||
let l = run (fun () -> xs |> List.ofArray |> List.averageBy f) | ||
let a = run (fun () -> xs |> Array.averageBy f) | ||
s = a && l = a | ||
|
||
[<Test>] | ||
let ``averageBy is consistent`` () = | ||
Check.QuickThrowOnFailure averageBy | ||
|
||
let contains<'a when 'a : equality> (xs : 'a []) x = | ||
let s = xs |> Seq.contains x | ||
let l = xs |> List.ofArray |> List.contains x | ||
|
@@ -54,6 +77,18 @@ let ``choose is consistent`` () = | |
Check.QuickThrowOnFailure contains<string> | ||
Check.QuickThrowOnFailure contains<float> | ||
|
||
let chunkBySize<'a when 'a : equality> (xs : 'a []) size = | ||
This comment has been minimized.
Sorry, something went wrong.
vasily-kirichenko
Collaborator
|
||
let s = run (fun () -> xs |> Seq.chunkBySize size |> Seq.map Seq.toArray |> Seq.toArray) | ||
let l = run (fun () -> xs |> List.ofArray |> List.chunkBySize size |> Seq.map Seq.toArray |> Seq.toArray) | ||
let a = run (fun () -> xs |> Array.chunkBySize size |> Seq.map Seq.toArray |> Seq.toArray) | ||
s = a && l = a | ||
|
||
[<Test>] | ||
let ``chunkBySize is consistent`` () = | ||
Check.QuickThrowOnFailure chunkBySize<int> | ||
Check.QuickThrowOnFailure chunkBySize<string> | ||
Check.QuickThrowOnFailure chunkBySize<float> | ||
This comment has been minimized.
Sorry, something went wrong.
vasily-kirichenko
Collaborator
|
||
|
||
let collect<'a> (xs : 'a []) f = | ||
let s = xs |> Seq.collect f | ||
let l = xs |> List.ofArray |> List.collect (fun x -> f x |> List.ofArray) | ||
|
@@ -112,28 +147,4 @@ let sort<'a when 'a : comparison> (xs : 'a []) = | |
let ``sort is consistent`` () = | ||
Check.QuickThrowOnFailure sort<int> | ||
Check.QuickThrowOnFailure sort<string> | ||
Check.QuickThrowOnFailure sort<NormalFloat> | ||
|
||
|
||
let averageFloat (xs : NormalFloat []) = | ||
let xs = xs |> Array.map float | ||
let s = run (fun () -> xs |> Seq.average) | ||
let l = run (fun () -> xs |> List.ofArray |> List.average) | ||
let a = run (fun () -> xs |> Array.average) | ||
s = a && l = a | ||
|
||
[<Test>] | ||
let ``average is consistent`` () = | ||
Check.QuickThrowOnFailure averageFloat | ||
|
||
let averageBy (xs : float []) f = | ||
let xs = xs |> Array.map float | ||
let f x = (f x : NormalFloat) |> float | ||
let s = run (fun () -> xs |> Seq.averageBy f) | ||
let l = run (fun () -> xs |> List.ofArray |> List.averageBy f) | ||
let a = run (fun () -> xs |> Array.averageBy f) | ||
s = a && l = a | ||
|
||
[<Test>] | ||
let ``averageBy is consistent`` () = | ||
Check.QuickThrowOnFailure averageBy | ||
Check.QuickThrowOnFailure sort<NormalFloat> |
1 comment
on commit 6f05f77
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, generic types are tricky. Since the whole thing is pretty messy in .NET I don't think there is a clean solution. E.g. even though some type says "I'm generic on type 'a" it can look at the actual 'a say using reflection and the signature does not expose this.
F#, in some sense, makes this worse because the ad hoc constraints like equality and comparison afaik are not visible using reflection, so I don't think there is an automatic way for FsCheck to pick up on that. I believe FsCheck will currently do "something" when it finds a generic type, which is to use the obj generator, which generates strings and ints and booleans (off the top of my head). I explicitly excluded things like floats for the reason @forki mentioned.
All in all FsCheck could use some heuristics with sensible defaults. But formally speaking, if a method is generic on its arguments it should not matter what type you pass in there - if it works for one, it works for all of them (theorems for free and all that.). Not the case in .NET.
I think it's better to use
(F (_, f))
instead of justf
, it will produce much more readable messages.