How to Sort Mongo collection in F# - mongodb

I can get a collection in MongoDB using F# No problem using
let draws = db.GetCollection<Draw>("draws").Find(fun _ -> true)
To Sort I would expect it to be:
let draws = db.GetCollection<Draw>("draws").Find(fun _ -> true).Sort(Builders<Draw>.Sort.Descending(d => d.drawDate))
But I am getting the following error. In the intellisense all of the types seem to be recognised all the way through so I am not sure what to do.
A unique overload for method 'Descending' could not be determined based on type information prior to this program point. A type annotation may be needed.

Your second lambda is using C# syntax. I'm not sure if that's what's causing the compiler error, but I think it's easier to do something like this anyway:
let draws =
db.GetCollection<Draw>("draws")
.Find(fun _ -> true)
.SortByDescending(fun d -> d.drawDate :> obj)
(Note that the SortByDescending function requires a result of explicit type object, but it shouldn't cause any problems for you. I think this is because the driver was created with C# clients in mind, where the upcast is implicit.)

Related

Swift: Chaining String/Substring methods yields 'ambiguous use of' errors. Fix or alternative?

I'm trying to do the most basic string manipulation using Swift. It looks like String provides everything I need, even though it relies on Substring intermediate results. So this works
let myString = "0123456789"
let mySubstring = myString.dropFirst(2)
print(mySubstring.dropLast(2))
It successfully yields "234567" as a Substring.
However, when I attempt to chain the calls...
print(myString.dropFirst(2).dropLast(2))
I get the following error...
9> print(myString.dropFirst(2).dropLast(2))
error: repl.swift:9:7: error: ambiguous use of 'dropFirst'
print(myString.dropFirst(2).dropLast(2))
^
Swift.Collection:39:17: note: found this candidate
public func dropFirst(_ n: Int) -> Self.SubSequence
^
Swift.Sequence:20:17: note: found this candidate
public func dropFirst(_ n: Int) -> AnySequence<Self.Element>
^
So it seems like the compiler is understandably having trouble inferring which dropFirst method to invoke because it is defined twice with different return types.
Is there a way around this? Is this just really poor API design on Apple's part? I'm trying to just get a nice easy to read and concise bit of code. I can also make it work by resorting to NSString but this seems wasteful and even more verbose and obtuse.
UPDATE:
I am able to get a better result by adding as Substring after the chain as in...
print(myString.dropFirst(2).dropLast(2) as Substring)
...since that disambiguates the overloaded methods. I would still love to see a more concise solution. Thanks.
If you define the return type, it has no trouble resolving which function to use. There are a number of ways to do this, such as:
let mySubstring: Substring = myString.dropFirst(2).dropLast(2)
Of course, as you say, you can insert this Substring type within the expression:
let mySubstring = (myString.dropFirst(2) as Substring).dropLast(2)
Surprisingly, it works if you reverse the order and do the dropLast first:
print(myString.dropLast(2).dropFirst(2))

Lens / Prism with error handling

Let's say I have a pair of conversion functions
string2int :: String -> Maybe Int
int2string :: Int -> String
I could represent these fairly easily using Optics.
stringIntPrism :: Prism String Int
However if I want to represent failure reason, I'd need to keep these as two separate functions.
string2int :: String -> Validation [ParseError] Int
int2string :: Int -> String`
For this simple example Maybe is perfectly fine, since we can always assume that a failure is a parse failure, thus we don't actually have to encode this using an Either or Validation type.
However imagine, in addition to my parsing Prism, I want to perform some validation
isOver18 :: Int -> Validation [AgeError] Int
isUnder55 :: Int -> Validation [AgeError] Int
It would be ideal to be able compose these things together, such that I could have
ageField = isUnder55 . isOver18 . string2Int :: ValidationPrism [e] String Int
This is fairly trivial to build by hand, however it seems like a common enough concept that there might be something lurking in the field of Lenses/Optics that does this already. Is there an existing abstraction that handles this?
tl;dr
Is there a standard way of implementing a partial lens / prism / iso that can be parameterised over an arbitrary functor instead of being tied directly to Maybe?.
I've used Haskell notation above since it's more straight forward, however I'm actually using Monocle in Scala to implement this. I would, however, be perfectly happy with an answer specific to i.e. ekmett's Lens library.
I have recently written a blog post about indexed optics; which explores a bit how we can do coindexed optics as well.
In short: Coindexed-optics are possible, but we have yet to do some further research there. Especially, because if we try to translate that approach into lens encoding of lenses (from Profunctor to VL) it gets even more hairy (but I think we can get away with only 7 type-variables).
And we cannot really do this without altering how indexed optics are currently encoded in lens. So for now, you'll better to use validation specific libraries.
To give a hint of the difficulties: When we try to compose with Traversals, should we have
-- like `over` but also return an errors for elements not matched
validatedOver :: CoindexedOptic' s a -> (a -> a) -> s -> (ValidationErrors, s)
or something else? If we could only compose Coindexed Prisms their value won't justify their complexity; they won't "fit" into optics framework.

Behavior of map() on Options

Im trying to map a JSONObject instance into an actual instance through Play Combinators. I am able to get the desrialization work correctly. The question is on the behavior of how map() works on an Option[JSONObject].
Option1:
jsonVal: Option[JSONObject] = getAsJson(input)
jsonVal.map(JSONUtil.fromJsonString(_.toString(), Blah.jsonReads))
Doesnt work, fails to compile as the _ is not resolved correctly. Compiler couldnt find the toString() on the object.
Option2:
jsonVal: Option[JSONObject] = getAsJson(input)
jsonVal.map(_.toString()).map(JSONUtil.fromJsonString(_, Blah.jsonReads))
Works !!. Can some one tell me why the Type of the default variable is not propagated when transformation is done as part of function argument?
It isn't behavior of map, it's behavior of _. It's just a shortcut for the normal function expression (in this case). In the first case you have
jsonVal.map(JSONUtil.fromJsonString(x => x.toString(), Blah.jsonReads))
which obviously doesn't work, and need to write the full version
jsonVal.map(x => JSONUtil.fromJsonString(x.toString(), Blah.jsonReads))

How can I serialize anything without specifying type?

I'm integrating with ZeroMQ and Akka to send case classes from different instances. Problem is that when I try to compile this code:
def persistRelay(relayEvent:String, relayData:Any) = {
val relayData = ser.serialize(relayData).fold(throw _, identity)
relayPubSocket ! ZMQMessage(Seq(Frame(relayEvent), Frame(relayData)))
}
The Scala compilers throws back recursive value relayData needs type.
The case classes going in are all different and look like Team(users:List[Long], teamId:Long) and so on.
Is there a method to allow any type in the serializer or a workaround? I'd prefer to avoid writing a serializer for every single function creating the data unless absolutely necessary.
Thanks!
This isn't really a typing issue. The problem is:
val relayData = ser.serialize(relayData).fold(throw _, identity)
You're declaring a val relayData in the same line that you're making a reference to the method parameter relayData. The Scala compiler doesn't understand that you have/want two variables with the same name, and, instead, interprets it as a recursive definition of val relayData. Changing the name of one of those variables should fix the error.
Regardless, since you didn't quite follow what the Scala compiler was asking for, I think that it would also be good to fill you in on what it is that the compiler even wanted from you (even though it's advice that, if followed, probably would have just led to you getting yet another error that wouldn't seem to make a lot of sense, given the circumstances).
It said "recursive value relayData needs type". The meaning of this is that it wanted you to simply specify the type of relayData by having
val relayData = ...
become something like
val relayData: Serializable = ...
(or, in place of Serializable, use whatever type it was that you wanted relayData to have)
It needs this information in order to create a recursive definition. For instance, take the simple case of
val x = x + 1
This code is... bizarre, to say the least, but what I'm doing is defining x in a (shallowly) recursive way. But there's a problem: how can the compiler know what type to use for the inner x? It can't really determine the type through type inference, because type inference involves leveraging the type information of other definitions, and this definition requires x's type information. Now, we might be able to infer that I'm probably talking about an Int, but, theoretically, x could be so many things! In fact, here's the ambiguity in action:
val x: Int = x + 1 // Default value for an Int is '0'
x: Int = 1
val y: String = y + 1 // Default value for a String is 'null'
y: String = null1
All that really changed was the type annotation, but the results are drastically different–and this is only a very simple case! So, yeah, to summarize all this... in most cases, when it's complaining about recursive values needing types, you should just have some empathy on the poor compiler and give it the type information that it so direly craves. It would do the same for you, DeLongey! It would do the same for you!

string option to string conversion

How do I convert the string option data type to string in Ocaml?
let function1 data =
match data with
None -> ""
| Some str -> str
Is my implementation error free? Here 'data' has a value of type string option.
To answer your question, yes.
For this simple function, you can easily find it in Option module. For example, Option.default totally fits your purpose:
let get_string data =
Option.default "" data
There are many other useful functions for working with option types in that module, you should check them out to avoid redefine unnecessary functions.
Another point is that the compiler would tell you if there's something wrong. If the compiler doesn't complain, you know that the types all make sense and that you have covered every case in your match expression. The OCaml type system is exceptionally good at finding problems while staying out of your way. Note that you haven't had to define any types yourself in this small example--the compiler will infer that the type of data is string option.
A lot of the problems the compiler can't detect are ones that we can't detect either. We can't tell whether mapping None to the empty string is what you really wanted to do, though it seems very sensible.