It's probably something very simple, but I'm new to FsCheck and not sure why the below raises the error it does ("Geneflect: type not handled System.Numerics.BigInteger")?
open System.Numerics
type NumericGenerator =
/// Generating BigIntegers (though only in the regular integer range for now)
static member BigInt() =
{ new Arbitrary<System.Numerics.BigInteger>() with
override x.Generator =
Arb.generate<int>
|> Gen.map (fun i -> new BigInteger(i)) }
[<Property>]
let ``Simple test`` (b: BigInteger) =
Arb.register<NumericGenerator> |> ignore
b + 1I = 1I + b
This is using FsCheck with xUnit integration.
FsCheck is trying to generate a BigInteger before calling your test, because the Arb.register call is in your test method itself. It then tries to do that via reflection, which fails.
You can tell FsCheck about your custom arbitrary instance by adding it as a argument to your property.
[<Property(Arbitrary=[|typeof<NumericGenerator>|])>]
Also, you can add the ArbitraryAttribute to the test's enclosing module to register that arbitrary instance for all the properties in the module. See https://github.com/fsharp/FsCheck/blob/master/tests/FsCheck.Test/Runner.fs for some examples.
One final tip - if you are generating a type that's easily converted to/from another already generated type, you can easily create a generate and a shrinker using the Arb.convert method. Something like:
Arb.Default.Int32() |> Arb.convert ...
shoud work.
Related
I'm trying to write custom equality constraint to compare 2 objects.
open FsUnit
open NUnit.Framework.Constraints
type equalCompany(expected:Company) =
inherit Constraints.EqualConstraint(expected)
override this.ApplyTo (actual:Company option) =
//actual.IsSome |> should equal True
//actual.Value.Id |> should equal expected.Id
ConstraintResult(this, actual, true)
// example of usage:
actualCompany |> should equalCompany expectedCompany
It complains because the ApplyTo implementation matches multiple overloads and I can't find the right syntax.
Ideally I like to compare to Company option but still just Company is fine.
The types involved are the following:
type CompanyType =
| Bank
| Exchange
type Company = {
Id: string
Types: CompanyType list
}
and I'm trying to write my equality constraint because the simple existing equal does not work properly with Types (the list, also if sorted, appears always different)
How can I properly override the ApplyTo function?
I think the issue is that the ApplyTo method that you are trying to override is generic and needs to have a signature ApplyTo<'T> : 'T -> ConstraintResult.
If I understand your code correctly, you are trying to define a comparison between Company and Company option. To Do this, you would need to check (at runtime) that the value passed to ApplyTo is of the right type. Then you can cast it and implement whatever logic you need.
Here is a minimal sample that worked for me, written as an F# script file:
#r "nuget: nunit"
#r "nuget: fsunit"
type Company(s) =
member x.Name = s
open FsUnit
open NUnit.Framework.Constraints
type equalCompany(expected:Company) =
inherit EqualConstraint(expected)
override this.ApplyTo<'T>(actual:'T) =
match box actual with
| :? option<Company> as co ->
ConstraintResult(this, actual,
co.IsSome && co.Value.Name = expected.Name)
| _ ->
ConstraintResult(this, actual, false)
let actualCompany = Company("Test")
let expectedCompany = Company("Test")
// This passes, because it has the right type
Some actualCompany |> should equalCompany expectedCompany
// This does not, because the 'ApplyTo' logic does not handle this type
actualCompany |> should equalCompany expectedCompany
I have an object of a class that I created, I am printing that object with %A format specifier, I see the typename Program+myclass instead of just myclass ? Why is that?
Someone might say that Program is the namespace, if so then how come I am not able to do the following ?
let o = Program+myclass()
Here is my full code
open System
type myclass() =
member val X = 3 with get,set
[<EntryPoint>]
let main argv =
let o = myclass()
o |> printfn "Here is myclass object %A"
Console.ReadKey()
0 // return an integer exit code
All classes are implicitly put inside a module.
Program is just the name of the module that is implicitly created when your program is only a single file.
For example, running the code in fsi will print
Here is myclass object FSI_0003+myclass
The prefix is just the name of the module. The compiler then hides this implementation so that you can't use it yourself, but you could if you used reflection.
As John correctly explains, the part before + in Program+myclass is there because your code is compiled to a Program module. F# modules are compiled to nested classes and so myclass is actually a nested class inside Program (which is a static class) and the + comes from the standard .NET naming of nested classes.
You can avoid this by putting the class in a namespace (but you'll still need to have the main function in a module):
namespace MyProgram
open System
type myclass() =
member val X = 3 with get,set
module Main =
[<EntryPoint>]
let main argv =
let o = myclass()
o |> printfn "Here is myclass object %A"
Console.ReadKey()
0 // return an integer exit code
Now, myclass is directly in a namespace (not as a nested class) and so it will print without the Program+ prefix.
I'm using the FSharp.Data typeproviders.
I would like to make a function that has a parameter that sets the typeprovider's sample string or file location.
let SyncIt url sample converter storer =
async {
url
|> MakeRequestAsync
|> Async.RunSynchronously
|> JsonProvider< sample >.Parse
|> Seq.iter (converter >> storer)
}
If a call the JsonProvider in the module with
[<Literal>]
let sample = """{"name":"Peter","age":9}"""
type provider = JsonProvider<sample>
works fine. Why can't I pass it as a parameter? I know it has something to do with the reference being clear at compile time, but cannot figure out how to get around it other than declaring each providers explicitly.
A function cannot take a value of static parameter as an argument, because the value has to be determined at compile time. This means that if you write:
let [<Literal>] sample = """{"name":"Peter","age":9}"""
let parseHtml html = JsonProvider<sample>.Parse(html)
... everything is fine, because the compiler knows that sample is a constant (and the compiler knows its value) and so it can instantiate the type provider (during compilation) to generate types. If you write something like:
let parseHtml sample html = JsonProvider<sample>.Parse(html)
... then the compiler cannot know what the value of sample may be at runtime and so it cannot generate the required types at compile time. Type providers do not "exist" at runtime, so the types cannot be generated on the fly (This would not be really useful, because the point of type providers is to give you some compile-time safety guarantees).
Your example. In your case, it might make sense to take the specific JsonProvider<sample>.Parse function as an argument instead:
let SyncIt url parse storer =
async {
url
|> MakeRequestAsync
|> Async.RunSynchronously
|> parse
|> Seq.iter (converter >> storer)
}
This way, the caller can specify the static parameter to a type provider and then call your function to do the synchronization:
let [<Literal>] sample = """{"name":"Peter","age":9}"""
SyncIt url (JsonProvider<sample>.Parse) storer
Although, it is not entirely clear to me why you need a type provider here. The point of providers is to give you nice types that you can use to access a concrete source of data. If your converter and storer work on any JSON data file, then you might be able to get the thing done using just JSON parser (also in F# Data).
Asynchronous block. Also, note that your code is not really running asynchronously - to make it asynchronous, you need to download the URL using let! operation:
let SyncIt url parser storer =
async {
let wc = new WebClient()
let! html = wc.AsyncDownloadString(url)
parser html
|> Seq.iter (converter >> storer)
}
I want to create a couple of computational expressions that would be used to access the database and return a list of items like so (I also have questions in the code comments):
let foo x y z = proc "foo" {
let! cmd = proc.CreateCommand() // can I do this?
do! In "x" DbType.Int32 // would i gain anything by replacing DbType with a union
// type since the names would match actual data types?
do! In "y" DbType.String 15;
cmd?x <- x
cmd?y <- y
use! r = cmd.ExecuteReader() // would this be bad form for creating a workflow builder?
return! r {
let item = MyItem()
do! item.a <- r.GetInt32("a")
do! item.a <- r.GetString("b")
do! item.c <- r.GetDateTime("c")
yield! item
}
}
How can I create a workflow builder such that an instance of it takes a parameter?
let proc name = ProcedureBuilder(connStr, factory) // how do I do this?
Yes, you can do this. You can use computation expression syntax after any expression with a type statically known to expose the right methods. So the following code works (but doesn't do anything particularly interesting):
let f x = async
let v = f "test" { return 1 }
Here, f has type 'a -> AsyncBuilder, so f "test" has type AsyncBuilder and can be followed with computation expression syntax. Your example of let proc name = ProcedureBuilder(connStr, factory) is perfectly fine, assuming that ProcedureBuilder is defined appropriately, though you presumably want name to appear somewhere in the constructor arguments.
The answer from Keith (kvb) is correct - you can use parameterized computation builders. The syntax of computation expressions is:
<expr> { <cexpr> }
So, the builder can be created by any expression. Usually, it is some value (e.g. async) but it can be a function call or even a constructor call. When using this, you would typically define a parameterized builder and then pass the argument to a constructor using a function (as #kvb suggests).
I actually wrote an example of this, not a long time ago, so I can share an example where - I think - this is quite useful. You can find it on F# snippets: http://fssnip.net/4z
The example creates a "special" asynchronous computation builder for ASP.NET MVC that behaves just like standard async. The only difference is that it adds Run member that uses AsyncManager (provided by ASP.NET) to execute the workflow.
Here are some relevant parts from the snippet:
/// A computation builder that is almost the same as stnadard F# 'async'.
/// The differnece is that it takes an ASP.NET MVC 'AsyncManager' as an
/// argumnet and implements 'Run' opration, so that the workflow is
/// automatically executed after it is created (using the AsyncManager)
type AsyncActionBuilder(asyncMgr:Async.AsyncManager) =
// (Omitted: Lots of boilerplate code)
/// Run the workflow automatically using ASP.NET AsyncManager
member x.Run(workflow) =
// Use 'asyncMgr' to execute the 'workflow'
The snippet wraps the construction in a base class, but you could define a function:
let asyncAction mgr = new AsyncActionBuilder(mgr)
And then use it to define asynchronous action in ASP.NET MVC:
member x.LengthAsync(url:string) = asyncAction x.AsyncManager {
let wc = new WebClient()
let! html = wc.AsyncDownloadString(url)
return html.Length }
Some apis like Ninject use fluent style apis, example:
Bind<ISomething>()
.To<Something>()
.WithConstructorArgument("arg1", "somevalue")
.OnActivation(x => x.DoSomething())
When I try format the code like this in F# the compiler complains at the whitespace between method calls.
Is it possible to put the method calls on seperate lines? I was thinking something like the pipelining operator |> but not exactly sure how in this case.
How should this be formatted in F#?
Are you sure this doesn't work?
Bind<ISomething>()
.To<Something>()
.WithConstructorArgument("arg1", "somevalue")
.OnActivation(fun x -> x.DoSomething())
(note one space before the .s)
Yeah, it's fine:
type ISomething = interface end
type Something = class end
type Foo() =
member this.To<'a>() = this //'
member this.WithConstructorArgument(s1,s2) = this
member this.OnActivation(x:Foo->unit) = this
member this.DoSomething() = ()
let Bind<'a>() = new Foo() //'
let r =
Bind<ISomething>()
.To<Something>()
.WithConstructorArgument("arg1", "somevalue")
.OnActivation(fun x -> x.DoSomething())
So long as you have some leading whitespace when you try to continue a single expression onto multiple lines, you're ok.
(Note that pipelining in general won't work unless you have APIs designed for it with curried method parameters.)