F# record member evaluation - f#

Why is t.b evaluated on every call? And is there any way how to make it evaluate only once?
type test =
{ a: float }
member x.b =
printfn "oh no"
x.a * 2.
let t = { a = 1. }
t.b
t.b

An alternative version of Brian's answer that will evaluate b at most once, but won't evaluate it at all if B is never used
type Test(a:float) =
// constructor
let b = lazy
printfn "oh no"
a * 2.
// properties
member this.A = a
member this.B = b.Value

It's a property; you're basically calling the get_b() member.
If you want the effect to happen once with the constructor, you could use a class:
type Test(a:float) =
// constructor
let b = // compute it once, store it in a field in the class
printfn "oh no"
a * 2.
// properties
member this.A = a
member this.B = b

In response to your comments in Brian's post, you can fake copy-and-update record expressions using optional/named args. For example:
type Person(?person:Person, ?name, ?age) =
let getExplicitOrCopiedArg arg argName copy =
match arg, person with
| Some(value), _ -> value
| None, Some(p) -> copy(p)
| None, None -> nullArg argName
let name = getExplicitOrCopiedArg name "name" (fun p -> p.Name)
let age = getExplicitOrCopiedArg age "age" (fun p -> p.Age)
member x.Name = name
member x.Age = age
let bill = new Person(name = "Bill", age = 20)
let olderBill = new Person(bill, age = 25)
printfn "Name: %s, Age: %d" bill.Name bill.Age
printfn "Name: %s, Age: %d" olderBill.Name olderBill.Age

The previous responses suggest switching to a class, instead of using a record. If you want to stay with records (for their simple syntax and immutability), you can take this approach:
type test =
{ a : float
b : float }
static member initialize (t: test) =
{ t with b = t.a * 2. }
This is useful if the instance of test is created by another library (like a data provider from a web service or database). With this approach, you must remember to pass any instance of test that you receive from that API through the initialize function before using it in your code.

Related

How to Access a Value from a Builder using Custom Operation in a Computation Expression

I have a Computational Expression Builder which receives
a value during construction
type SomeBuilder<'e> (e: 'e) =
member this.Bind(x, fn) = ...
member this.Return x = ...
member this.ReturnFrom x = ...
let buildSome v = SomeBuilder(v)
buildSome 2 {
return 1
}
Now I'd like to access the value e from within the
Computational Expression via a custom operation so that
buildSome 2 {
return 1 + e()
}
So I really want to access properties/values in the underlying builder object and work with them
I imagine I would need something like
type SomeBuilder<'e> (e: 'e) =
member this.Bind(x, fn) = ...
member this.Return x = ...
member this.ReturnFrom x = ...
[<CustomOperation("e")>]
member this.E () = e
but that doesn't work.
So my question is
a) is something like this possible using CustomOperations and Computational Expressions
b) and if it is possible, how?
Disclaimer:
As usual in programming there is a million ways to achieve similar effects
in completely different ways. I am explicitly asking for this particular way
and I am OK if the answer is simply "No". But please refrain from answers that are non answers in the narrowest sense laid out here.
I'm not sure you'll like my answer and whether it's within your boundaries, but you could capture the builder instance using a trick like this:
type SomeBuilder<'e> (e: 'e) =
member this.Value = e
[<CustomOperation("extract", MaintainsVariableSpaceUsingBind = true, AllowIntoPattern = true)>]
member this.Extract (state) = this
member this.Bind(x, fn) = fn x
member this.Return x = x
member this.ReturnFrom x = x
let builder e = new SomeBuilder<_>(e)
let x = builder 1 {
extract into builder // now we've brought builder in the scope
printfn "here we can read the value = %d" builder.Value
return 0
}
To show that primary constructor arguments are in scope for the builder's instance methods:
type SomeBuilder<'e> (e: 'e) =
member __.Bind(x, fn) = fn x
member __.Return x = x
[<CustomOperation("e", MaintainsVariableSpaceUsingBind = true, AllowIntoPattern = true)>]
member __.E _ = e
SomeBuilder 2 {
e into i
return 1 + i }
// val it : int = 3
SomeBuilder "bar" {
e into s
return "foo" + s }
// val it : string = "foobar"
Consider the position of the custom operation inside the builder; it will ignore expressions that precede it.

polymorphism with types for common fields

Is this question solvable through functional idiomatic approach, could generics or discriminated unions be the answer?
Is it possible to have polymorphism with passing different types to a function while the function is consuming some common fields.
Idea is to be able to call and reuse the function with different types and use the common attributes/fields.
type Car = {
Registration: string
Owner: string
Wheels: int
customAttribute1: string
customAttribute2: string
}
type Truck = {
Registration: string
Owner: string
Wheels: int
customField5: string
customField6: string
}
let SomeComplexMethod (v: Car) =
Console.WriteLine("Registration" + v.Registration + "Owner:" + v.Owner + "Wheels" + v.Wheels
// some complex functionality
Use
SomeComplexMethod(car)
SomeComplexMethod(truck)
Edit
Following the answer. Is it possible to specify the type of the incoming v since JSON serializer asks for the associated type. If Car was supplied as input, Car will be output, If truck as input truck will be output.
let inline someComplexFun v =
let owner = (^v: (member Owner: string)(v))
let registration = (^v: (member Registration: string)(v))
// process input
use response = request.GetResponse() :?> HttpWebResponse
use reader = new StreamReader(response.GetResponseStream())
use memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(reader.ReadToEnd()))
(new DataContractJsonSerializer(typeof<Car>)).ReadObject(memoryStream) :?> Car
if truck was the input v
(new DataContractJsonSerializer(typeof<Truck>)).ReadObject(memoryStream) :?> Truck
This looks like the classical use case for object inheritance, or perhaps an interface. The difference is that an interface provides only methods (including properties, as they are methods under the hood), while a base object (abstract or concrete) can also provide fields.
In your case an interface might be appropriate:
type IVehicle =
abstract Registration : string
abstract Owner : string
abstract Wheels : int
type Car (_r, _o, _w) =
member customAttribute1 : string
member customAttribute2 : string
interface IVehicle with
member Registration = _r
member Owner = _o
member Wheels = _w
type Truck (_r, _o, _w) =
member customField5 : string
member customField6 : string
interface IVehicle with
member Registration = _r
member Owner = _o
member Wheels = _w
let someComplexMethod (v : IVehicle) =
stdout.WriteLine "Registration: " + v.Registration +
"\nOwner: " + v.Owner +
"\nWheels: " + v.Wheels
EDIT: You can do it without OOP by using a discriminated union, and several record types:
type VehicleBase =
{ Registration : string
Owner : string
Wheels : int }
type CarAttributes =
{ customAttribute1 : string
customAttribute2 : string }
type TruckAttributes =
{ customField5 : string
customField6 : string }
type Vehicle =
| Car of VehicleBase * CarAttributes
| Truck of VehicleBase * TruckAttributes
let processVehicle v =
stdout.WriteLine ("Registration: " + v.Registration +
"\nOwner: " + v.Owner +
"\nWheels: " + v.Wheels)
let someComplexMethod = function
| Car (v, _) -> processVehicle v
| Truck (v, _) -> processVehicle v
What you want is usually called structural (or duck) typing. It can be done via interfaces and object expressions in F# (the accepted way) or via SRTPs. The link #CaringDev provided gives you a quick rundown, but obviously you can find many more examples. Please read this and this. For your specific example it will depend how much control you have over the original types.
It's easy to define another type that includes the fields that you might want. Then your function (I found it interesting btw, that you so much want to go for a functional solution but named it a method...) should just take ANY type that has the required fields/properties. Generics won't work for you in this case, as you need to constrain to a subset of types. But once you have such a function, which uses statically resolved type parameters (SRTPs) you're good to go:
type Car = {
Registration: string
Owner: string
Wheels: int
customAttribute1: string
customAttribute2: string
}
type Truck = {
Registration: string
Owner: string
Wheels: int
customField5: string
customField6: string
}
type Bike = {
Owner: string
Color: string
}
type Vehicle = {
Registration: string
Owner: string
}
let inline someComplexFun v =
let owner = (^v: (member Owner: string)(v))
let registration = (^v: (member Registration: string)(v))
{Registration = registration; Owner = owner}
let car = {Car.Registration = "xyz"; Owner = "xyz"; Wheels = 3; customAttribute1= "xyz"; customAttribute2 = "xyz"}
let truck = {Truck.Registration = "abc"; Owner = "abc"; Wheels = 12; customField5 = "abc"; customField6 = "abc"}
let bike = {Owner = "hell's angels"; Color = "black"}
someComplexFun car //val it : Vehicle = {Registration = "xyz";
//Owner = "xyz";}
someComplexFun truck //val it : Vehicle = {Registration = "abc";
//Owner = "abc";}
someComplexFun bike //error FS0001:
The Vehicle type is defined but it could be anything. Then someConplexFun is defined that can take any type, that has Owner and Registration. It has to be inline and its type signature is:
val inline someComplexFun :
v: ^v -> Vehicle
when ^v : (member get_Owner : ^v -> string) and
^v : (member get_Registration : ^v -> string)
You can pass any type that has Owner and Registration fields, and it will return a Vehicle but of course you can just print it out or return a tuple, etc. For the Bike type, since it doesn't have Registration this function will fail.
There are multiple ways how to solve this problem. Besides the already shown solution, i would use lambda functions or a new datatsructure, to solve this problem.
The idea with a lambda is. Instead of a value you expect a function as an argument that returns the needed value. As an example:
let printInformation registration owner wheels obj =
let reg = registration obj
let owner = owner obj
let wheels = wheels obj
printfn "Registration: %s Owner: %s Wheels: %d" reg owner wheels
let car = {Registration="CAR"; Owner="Me"; Wheels=4; customAttribute1="A"; customAttribute2="B"}
let truck = {Registration="TRUCK"; Owner="You"; Wheels=6; customField5="A"; customField6="B"}
printInformation
(fun (obj:Car) -> obj.Registration)
(fun obj -> obj.Owner)
(fun obj -> obj.Wheels)
car
printInformation
(fun (obj:Truck) -> obj.Registration)
(fun obj -> obj.Owner)
(fun obj -> obj.Wheels)
truck
But the whole idea is that you create such a function once for each type, and use partial application.
let printCar =
printInformation
(fun (obj:Car) -> obj.Registration)
(fun obj -> obj.Owner)
(fun obj -> obj.Wheels)
let printTruck =
printInformation
(fun (obj:Truck) -> obj.Registration)
(fun obj -> obj.Owner)
(fun obj -> obj.Wheels)
printCar car
printTruck truck
Based on this you can create a dispatch function, if you wish
let print obj =
match box obj with
| :? Car as c -> printCar c
| :? Truck as t -> printTruck t
| _ -> failwith "Not Car or Truck"
print car
print truck
print "FooBar"
Now the first ttwo works, but you lose type-safety. The third one compiles, but creates a runtime exception.
Working with lambdas is good enough if you only have 1-3 values, but if you need more values, then it can become cumbersome. Another idea would be to create your own data-type for your function, and provide conversation functions instead.
type Information = {
Registration: string
Owner: string
Wheels: int
}
let printInfo (info:Information) =
printfn "Registration: %s Owner: %s Wheels: %d" info.Registration info.Owner info.Wheels
The advantage. Now you relay on data instead of types. You can basically print any type as long you can create an Information record out of it. So its just a matter of providing a single transformation function for each type.
let carToInformation (car:Car) : Information =
{Registration=car.Registration; Owner=car.Owner; Wheels=car.Wheels}
let truckToInformation (truck:Truck) : Information =
{Registration=truck.Registration; Owner=truck.Owner; Wheels=truck.Wheels}
printInfo (carToInformation car)
printInfo (truckToInformation truck)
Sure, you can once again create a dispatch function based on this idea. Its up to you, but my personal approach i would create an Information type and use explicit conversation instead.
In my opinion it is the easiest to understand, and also the most useful one, as you can easily print any type this way as long you somehow can provide the needed data. And your different types don't need to share a common interface with pre-defined fields that have some special logic in it.

F# type definition with expression

Is it possible to express something like this:
type id = int > 0
I know its not possible to do statically, since this would mean F# has dependent types. In C# I'm used to do this sort of thing with code contracts and get a runtime enforcement. I'm looking for something similiar here.
Thanks
EDIT:
Thank you for all the answers which have various pros and cons. At the monent I'm only using a small subset of F#, a subset of the ocaml core that lends itself easily to program proofs. So no classes.
Contrary to what others said, I would suggest not using classes here, if I understood your problem correctly.
Since the value is immutable, we need applying constraint only once. Any wrapper classes would be an overhead and load GC. Instead, a simple function will do the job:
let inline constrained predicate errormessage value =
if not (predicate value)
then invalidArg "value" errormessage
else value
let positive =
constrained (fun x -> x > 0) "Value must be positive"
let int1 = positive 5 // OK
let int2 = positive -3 // ArgumentException
You can do the same for other types:
let mustBeLong =
constrained (fun (x:string) -> x.Length > 3) "String must be long"
let str1 = mustBeLong "foobar" // OK
let str2 = mustBeLong "baz" // ArgumentException
Using the same within a struct:
type Point2D =
struct
val X: int
val Y: int
new(x: int, y: int) = { X = positive x; Y = positive y }
end
let point1 = Point2D(5, 3) // OK
let point2 = Point2D(5, -2) // ArgumentException
Define it as a union type:
type Id = Id of int
and shadow the constructor with another function:
let Id n =
assert(n > 0)
Id n
In F#, you have to resort to classes and check arguments inside constructors. Other types such as discriminated unions, records and structs have implicit constructors which you can't easily alter.
type Id(i: int) =
do if i <= 0 then
invalidArg "i" "the argument has to be a positive integer"
member x.Value = i
Pattern matching doesn't play nicely with classes. You can remedy the problem using active patterns:
let (|Id|) (id: Id) = id.Value
let id = Id(1)
match id with
| Id 1 -> printfn "matched"
| _ -> printfn "unmatched"
You could create a generic class like so:
type verify<'t>(t:'t,cond) =
let mutable tval = t
let _verify v = if not (cond v) then failwith "bad argument"
do _verify tval
member x.get() = tval
member x.set v =
_verify v
tval <- v
then you can use it with
verify(1,fun t -> t>0)
using .set will recheck the condition.

how do i fix these errors generated by my computational expression that is using my custom workflow builder?

From the MSDN documentation I understand that if Run is implemented it will be called automatically at the end of the computational expression. It says that:
builder.Run(builder.Delay(fun () -> {| cexpr |}))
will be generated for the computational expression. Run and/or Delay will be omitted if they are not defined in the workflow builder. I was expecting my ReaderBuilder to return a list of MyItem objects when Run is called automatically. So I do not understand why I'm getting a type mismatch error. The errors are generated by the return statement inside the ProcedureBuilder foo at the end of my code listing here. Could someone please explain what I'm misunderstanding about workflow builders and what I have implemented incorrectly?
I'm getting the following errors:
The type ''a list' is not compatible with the type 'ReaderBuilder'
Type constraint mismatch. The type 'a list is not compatible with type ReaderBuilder The type ''a list' is not compatible with the type 'ReaderBuilder'
open System
open System.Data
open System.Data.Common
open System.Configuration
let config = ConfigurationManager.ConnectionStrings.Item("db")
let factory = DbProviderFactories.GetFactory(config.ProviderName)
type Direction =
| In
| Out
| Ref
| Return
type dbType =
| Int32
| String of int
type ReaderBuilder(cmd) =
let mutable items = []
member x.Foo = 2
member x.YieldFrom item =
items <- item::items
item
member x.Run item =
items
type ProcBuilder(procedureName:string) =
let name = procedureName
let mutable parameters = []
let mutable cmd:DbCommand = null
let mutable data = []
member x.Command with get() = cmd
member x.CreateCommand() =
factory.CreateCommand()
member x.AddParameter(p:string*dbType*Direction) =
parameters <- p::parameters
member x.Bind(v,f) =
f v
member x.Reader = ReaderBuilder(cmd)
member x.Return(rBuilder:ReaderBuilder) =
data
let (?<-) (builder:ProcBuilder) (prop:string) (value:'t) =
builder.Command.Parameters.[prop].Value <- value
type MyItem() =
let mutable _a = 0
let mutable _b = String.Empty
let mutable _c = DateTime.Now
member x.a
with get() = _a
and set n = _a <- n
member x.b
with get() = _b
and set n = _b <- n
member x.c
with get() = _c
and set n = _c <- n
let proc name = ProcBuilder(name)
let (%) (builder:ProcBuilder) (p:string*dbType*Direction) =
builder.AddParameter(p)
builder
let (?) (r:DbDataReader) (s:string) = r.GetOrdinal(s)
let foo x y =
let foo = proc "foo" % ("x", Int32, In) % ("y", String(15), In)
foo?x <- x
foo?y <- y
foo {
do! foo?x <- x
do! foo?y <- y
return foo.Reader {
let item = MyItem()
item.a <- r.GetInt32("a")
item.b <- r.GetString("b")
item.c <- r.GetDateTime("c")
yield! item
}
}
The problem in your example is that the foo.Reader { ... } block has a return type MyItem list (because this is what the Run member of the ReaderBuilder type returns). However, the Return member of ProcBuilder expects an argument of type ReaderBuilder.
The data field of ReaderBuilder will be always an empty list, so this is also suspicious. I think you probably want to change the Return of ProcBuilder to take an argument MyItem list instead.
However, I think that using custom computation builder for database access doesn't really give you much advantage. You're not creating a "non-standard computation" in some sense. Instead, you probably just want a nice syntax for calling commands & reading data. Using the dynamic operator can make this quite elegant even without computation builders - I wrote an article about this some time ago.

How to check if an event is being handled in F#

What is the F# equivalent of the following C# code? Specifically, I need to check if an event is being handled.
protected virtual void OnClicked(ClickEventArgs e) {
if (this.Clicked != null) //how can I perform this check in F#
this.Clicked(this, e);
}
Okay, I think I figured this thing out. Taking a cue from Don Syme's blog, specifically the section "The Implementation of the IEvent Module."
Instead of the following:
let validationFailedEvent = new Event<DataValidationEventHandler, DataValidationEventArgs>()
I had to implement IEvent myself and create a variable to hold the invocation list:
let mutable listeners: Delegate = null
let validationFailedEvent = { new IEvent<DataValidationEventHandler, DataValidationEventArgs> with
member x.AddHandler(d) =
listeners <- Delegate.Combine(listeners, d)
member x.RemoveHandler(d) =
listeners <- Delegate.Remove(listeners, d)
member x.Subscribe(observer) =
let h = new Handler<_>(fun sender args -> observer.OnNext(args))
(x :?> IEvent<_,_>).AddHandler(h)
{ new System.IDisposable with
member x.Dispose() = (x :?> IEvent<_,_>).RemoveHandler(h) } }
Then, to check if there are listeners, and, if not, raise an exception:
member private x.fireValidationFailedEvent(e:DataValidationEventArgs) =
match listeners with
| null -> failwith "No listeners"
| d -> d.DynamicInvoke([| box x; box e |])
An alternative way to implement RequiresSubscriptionEvent is to build on top of the existing Event functionality (using composition) and just add a counter that counts the number of registered handlers and add a property HasListeners (or even publish the number of listeners if you wanted...)
This makes the code a bit easier to use and hopefuly also safer, because if you don't check whether it has any listneres, it will still work as the usual F# code. And if you want to perform the check, you can...
type RequiresSubscriptionEvent<_>() =
let evt = new Event<_>()
let mutable counter = 0
let published =
{ new IEvent<_> with
member x.AddHandler(h) =
evt.Publish.AddHandler(h)
counter <- counter + 1;
member x.RemoveHandler(h) =
evt.Publish.RemoveHandler(h)
counter <- counter - 1;
member x.Subscribe(s) =
let h = new Handler<_>(fun _ -> s.OnNext)
x.AddHandler(h)
{ new System.IDisposable with
member y.Dispose() = x.RemoveHandler(h) } }
member x.Trigger(v) = evt.Trigger(v)
member x.Publish = published
member x.HasListeners = counter > 0
Sample usage:
type Demo() =
let evt = new RequiresSubscriptionEvent<_>()
[<CLIEvent>]
member x.OnSomething = evt.Publish
member x.FooThatFiresSomething() =
if evt.HasListeners then
evt.Trigger("foo!")
else
printfn "No handlers!"
Even though this isn't a part of standard F# libraries, it shows the great advantage of F# first class events. If there is some missing functionality, you can simply implement it yourself!
Typically, you don't need to do that check in F# (the event infrastructure checks for you):
type T() =
let ev = new Event<_>()
[<CLIEvent>]
member x.Event = ev.Publish
member x.OnClicked() =
ev.Trigger()
I followed kvb's suggestion and put this logic in a class. I copied Event from the F# sources and added a Handled property, which checks if the Delegate is null. I tried adding to, then removing handlers from the event to make sure it gets set back to null, and indeed it does.
type EventEx<'Delegate,'Args when 'Delegate : delegate<'Args,unit> and 'Delegate :> System.Delegate >() =
let mutable multicast : System.Delegate = null
static let argTypes =
let instanceBindingFlags = BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.DeclaredOnly
let mi = typeof<'Delegate>.GetMethod("Invoke",instanceBindingFlags)
mi.GetParameters() |> (fun arr -> arr.[1..]) |> Array.map (fun p -> p.ParameterType)
member x.Handled = (multicast <> null)
member x.Trigger(sender:obj,args:'Args) =
match multicast with
| null -> ()
| d ->
if argTypes.Length = 1 then
d.DynamicInvoke([| sender; box args |]) |> ignore
else
d.DynamicInvoke(Array.append [| sender |] (Microsoft.FSharp.Reflection.FSharpValue.GetTupleFields(box args))) |> ignore
member x.Publish =
{ new IEvent<'Delegate,'Args> with
member x.AddHandler(d) =
multicast <- System.Delegate.Combine(multicast, d)
member x.RemoveHandler(d) =
multicast <- System.Delegate.Remove(multicast, d)
member e.Subscribe(observer) =
let h = new Handler<_>(fun sender args -> observer.OnNext(args))
(e :?> IEvent<_,_>).AddHandler(h)
{ new System.IDisposable with
member x.Dispose() = (e :?> IEvent<_,_>).RemoveHandler(h) } }
This article here http://geekswithblogs.net/Erik/archive/2008/05/22/122302.aspx says you do not need to check for null events in F#, though I don't know what his reference is.
This article http://blogs.msdn.com/dsyme/articles/FSharpCompositionalEvents.aspx by Don Symes goes into F# events in quite a bit of detail. It looks like events are not owned by the class in F#
From the above,
it is that events are now first-class
values in the F# langauge. Indeed,
events are not a separate notion at
all in the language design, rather,
events are just values of type
Microsoft.FSharp.Idioms.IEvent<_>, and
.NET events are effectively just
properties of this type.
And
One of the restrictions of C# is that
events can only exist as members
within classes. With the F# model,
new event values can be created just
as values as part of any expression.

Resources