What are the pros and cons of each of the following two ways to create a tree node?
type TreeNode = | TreeNode of int * (TreeNode option) * (TreeNode option) * (TreeNode option)
type Node = | Node of int * Node * Node
| None
They are very close, but not entirely equivalent. You can actually reason about functional types quite nicely using mathematics (see for example my recent article), but you can see that even informally.
Given any TreeNode(num, optLeft, optRight), you can always create a Node containing the same information (None of the option type will be mapped to Node.None).
Interestingly, this does not work the other way round. If someone gives you Node.None, you cannot turn it into TreeNode, because TreeNode needs at least one integer in the root.
So, they are equivalent with the exception that the second one allows empty trees. From the practical perspective, the second type seems easier to use (because you only have to handle empty tree in one place).
Related
I seem to often run into cases where I want to generate some complex structure, but a special variation with a member type generated differently.
For example, consider this tree
type Tree<'LeafData,'INodeData> =
| LeafNode of 'LeafData
| InternalNode of 'INodeData * Tree<'LeafData,'INodeData> list
I want to generate cases like
No internal node is childless
There are no leaf-type nodes
Only a limited subset of leaf types are used
These are simple to do if I override all generation of a corresponding child type.
The problem is that it seems register is inherently a thread-level action, and there is no gen-local alternative.
For example, what I want could look like
let limitedLeafs =
gen {
let leafGen = Arb.generate<LeafType> |> Gen.filter isAllowedLeaf
do! registerContextualArb (leafGen |> Arb.fromGen)
return! Arb.generate<Tree<NodeType, LeafType>>
}
This Tree example specifically can work around with some creative type shuffling, but that's not always possible.
It's also possible to use some sort of recursive map that enforces assumptions, but that seems relatively complex if the above is possible. I might be misunderstanding the nature of FsCheck generators though.
Does anyone know how to accomplish this kind of gen-local override?
There's a few options here - I'm assuming you're on FsCheck 2.x but keep scrolling for an option in FsCheck 3.
The first is the most natural one but is more work, which is to break down the generator explicitly to the level you need, and then put humpty dumpty together again. I.e don't rely on the type-based generator derivation so much - if I understand your example correctly that would mean implementing a recursive generator - relying on Arb.generate<LeafType> for the generic types.
Second option - Config has an Arbitrary field which you can use to override Arbitrary instances. These overrides will take effect even if the overridden types are part of the automatically generated ones. So as a sketch you could try:
Check.One ({Config.Quick with Arbitrary = [| typeof<MyLeafArbitrary>) |]) (fun safeTree -> ...)
More extensive example which uses FsCheck.Xunit's PropertyAttribute but the principle is the same, set on the Config instead.
Final option! :) In FsCheck 3 (prerelease) you can configure this via a new (as of yet undocumented) concept ArbMap which makes the map from type to Arbitrary instance explicit, instead of this static global nonsense in 2.x (my bad of course. seemed like a good idea at the time.) The implementation is here which may not tell you all that much - the idea is that you put an ArbMap instance together which contains your "safe" generators for the subparts, then you ArbMap.mergeWith that safe map with ArbMap.defaults (thus overriding the default generators with your safe ones, in the resulting ArbMap) and then you use ArbMap.arbitrary or ArbMap.generate with the resulting map.
Sorry for the long winded explanation - but all in all that should give you the best of both worlds - you can reuse the generic union type generator in FsCheck, while surgically overriding certain types in that context.
FsCheck guidance on this is:
To define a generator that generates a subset of the normal range of values for an existing type, say all the even ints, it makes properties more readable if you define a single-case union case, and register a generator for the new type:
As an example, they suggest you could define arbitrary even integers like this:
type EvenInt = EvenInt of int with
static member op_Explicit(EvenInt i) = i
type ArbitraryModifiers =
static member EvenInt() =
Arb.from<int>
|> Arb.filter (fun i -> i % 2 = 0)
|> Arb.convert EvenInt int
Arb.register<ArbitraryModifiers>() |> ignore
You could then generate and test trees whose leaves are even integers like this:
let ``leaves are even`` (tree : Tree<EvenInt, string>) =
let rec leaves = function
| LeafNode leaf -> [leaf]
| InternalNode (_, children) ->
children |> List.collect leaves
leaves tree
|> Seq.forall (fun (EvenInt leaf) ->
leaf % 2 = 0)
Check.Quick ``leaves are even`` // output: Ok, passed 100 tests.
To be honest, I like your idea of a "gen-local override" better, but I don't think FsCheck supports it.
I am having an F# exam in 10 days and as I am currently doing old exam sets, I ran into a problem understanding generics and especially types that have two polymorphic arguments.
The questions should be rather easy to solve, but how it works syntactically, I am not sure.
The old exam question is as follows:
The following type Sum<'a,'b> comprises two different kinds of values
type Sum<'a,'b> =
| Left of 'a
| Right of 'b
Now I need to write two values of type Sum<int list, bool option>, one should be defined using Left and the other Right.
If you define let sum1 = Left "Hello World it evaluates to val sum1 : Sum<string,'a>, but I cannot find a way to create Sum<int list, bool option>.
How would you solve it?
if you were to write
let sum1 = Sum<string,int>.Left "Hello World"
you would get a Sum<string,int>
so if you need a Sum<int list, bool option> then.....
(to be fair, in real life, having a Sum<string,'a> is not really an issue as 'a can become anything and if it needs to be a bool option or whatever, the type inference will usually do the hard work for you and constrain 'a).
I'm seeking for best practices in modeling request-response based system using functional approach in F#.
Generalized case requirements for example:
there are many request/response pair types: A, B, C, etc
each response must represent two states: succeed and failed
each request consists of common data piece and specific A/B/... data piece
while processing, request may be rejected both for common and specific reasons
As for now, I end up with following design:
type CommonData = {...}
type RequestMessage =
| ARequestMessage of CommonData * ARequestData
| BRequestMessage of CommonData * BRequestData
...
type Response<'S, 'F> =
| Success of 'S
| Failure of 'F
type ResponseMessage =
| AResponseMessage of Response<AResponseSuccess, AResponseFailure>
| BResponseMessage of Response<BResponseSuccess, BResponseFailure>
...
where AResponseSuccess and BResponseSuccess contains same discriminated union cases or ResponseMessage type is covered by GeneralResponseMessage type like
type GeneralResponseMessage =
| CommonFailure of CommonResponseFailure
| SpecificResponse of ResponseMessage
both cases look terrible and I can't figure out more clear and elegant solution.
Edit
System processes requests in statemachine-manner over single evolving state, so it isn't possible to separate different types of request processing
This may be better suited for https://codereview.stackexchange.com/, but let me try to answer this here.
My take on this would be to group the operations vertically, not horizontally. What I mean by that is that instead of grouping all requests in one type and all responses in another, I would pair up the corresponding request and response types, and build a generic wrapper for the processing itself.
In your case, the processing fundamentally is a function of type RequestMessage -> GeneralResponseMessage. I propose generalizing this into the following:
type ProcessRequest<'requestData, 'responseMessage, 'responseFailure> =
CommonData -> 'requestData ->
Result<'responseMessage, ErrorResponse<'responseFailure>>
and ErrorResponse<'responseFailure> =
| CommonFailure of CommonResponseFailure
| SpecificResponse of 'responseFailure
Just a note here, I use Result from FSharp.Core instead of your Response type, as they model the exact same thing.
Then you can create a specific instances, for example
type AProcessRequest =
ProcessRequest<ARequestMessage, AResponseMessage, AResponseFailure>
And this can then be used to process specific messages. In your case, the processing logic would have to match on RequestMessage case and proceed based on that, in my case you have to this match before calling the specific processor, but if you need it grouped in one type, you can always do something this to supply all the implementations as a single piece of data
type ProcessMessage =
{ A : AProcessRequest
B : BProcessRequest
C : ... }
and you can supply the implementations in composition root.
If you don't like so many specific types, you don't have to give names to the concrete instances of the generic processor, C : ProcessMessage<CRequestMessage, CResponseMessage, CResponseFailure> will do just fine, but may be less readable if there are many instances of similar types.
I have an object that can be neatly described by a discriminated union. The tree that it represents has some properties that can be easily updated when the tree is modified (but remaining immutable) but that are relatively expensive to recalculate.
I would like to store those properties along with the object as cached values but I don't want to put them into each of the discriminated union cases so I figured a member variable would fit here.
The question is then, how do I change the member value (when I modify the tree) without mutating the actual object? I know I could modify the tree and then mutate that copy without ruining purity but that seems like a wrong way to go about it to me. It would make sense to me if there was some predefined way to change a property but so that the result of the operation is a new object with that property changed.
To clarify, when I say modify I mean doing it in a functional way. Like (::) "appends" to the beginning of a list. I'm not sure what the correct terminology is here.
F# actually has syntax for copy and update records.
The syntax looks like this:
let myRecord3 = { myRecord2 with Y = 100; Z = 2 }
(example from the MSDN records page - http://msdn.microsoft.com/en-us/library/dd233184.aspx).
This allows the record type to be immutable, and for large parts of it to be preserved, whilst only a small part is updated.
The cleanest way to go about it would really be to carry the 'cached' value attached to the DU (as part of the case) in one way or another. I could think of several ways to implement this, I'll just give you one, where there are separate cases for the cached and non-cached modes:
type Fraction =
| Frac of int * int
| CachedFrac of (int * int) * decimal
member this.AsFrac =
match this with
| Frac _ -> this
| CachedFrac (tup, _) -> Frac tup
An entirely different option would be to keep the cached values in a separate dictionary, this is something that makes sense if all you want to do is save some time recalculating them.
module FracCache =
let cache = System.Collections.Generic.Dictionary<Fraction, decimal>()
let modify (oldFrac: Fraction) (newFrac: Fraction) =
cache.[newFrac] <- cache.[oldFrac] + 1 // need to check if oldFrac has a cached value as well.
Basically what memoize would give you plus you have more control over it.
So, by a hilarious series of events, I downloaded the FParsec source and tried to build it. Unfortunately, it's not compatible with the new 1.9.9.9. I fixed the easy problems, but there are a couple of discriminated unions that still don't work.
Specifically, Don Syme's post explains that discriminated unions containing items of type obj or -> don't automatically get equality or comparison constraints, since objects don't support comparison and functions don't support equality either. (It's not clear whether the automatically generated equality/comparison was buggy before, but the code won't even compile now that they're no longer generated.)
Here are some examples of the problematic DUs:
type PrecedenceParserOp<'a,'u'> =
| PrefixOp of string * Parser<unit,'u> * int * bool * ('a -> 'a)
| others ...
type ErrorMessage =
| ...
| OtherError of obj
| ...
Here are the offending uses:
member t.RemoveOperator (op: PrecedenceParserOp<'a, 'u>) =
// some code ...
if top.OriginalOp <> op then false // requires equality constraint
// etc etc ...
or, for the comparison constraint
let rec printMessages (pos: Pos) (msgs: ErrorMessage list) ind =
// other code ...
for msg in Set.ofList msgs do // iterate over ordered unique messages
// etc etc ...
As far I can tell, Don's solution of tagging each instance with a unique int is the Right Way to implement a custom equality/comparison constraint (or a maybe a unique int tuple so that individual branches of the DU can be ordered). But this is inconvenient for the user of the DU. Now, construction of the DU requires calling a function to get the next stamp.
Is there some way to hide the tag-getting and present the same constructors to users of the library? That is, to change the implementation without changing the interface? This is especially important because it appears (from what I understand of the code) that PrecedenceParserOp is a public type.
What source did you download for FParsec? I grabbed the latest from the FParsec BitBucket repository, and I didn't have to make any changes at all to the FParsec source to get it to compile in VS 2010 RC.
Edit: I take that back. I did get build errors from the InterpLexYacc and InterpFParsec sample projects, but the core FParsec and FParsecCS projects build just fine.
One thing you could do is add [<CustomEquality>] and [<CustomComparison>] attributes and define your own .Equals override and IComparable implementation. Of course, this would require you to handle the obj and _ -> _ components yourself in an appropriate way, which may or may not be possible. If you can control what's being passed into the OtherError constructor, you ought to be able to make this work for the ErrorMessage type by downcasting the obj to a type which is itself structurally comparable. However, the PrecendenceParserOp case is a bit trickier - you might be able to get by with using reference equality on the function components as long as you don't need comparison as well.