I can't understand why this
let data =
JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(
File.ReadAllText <| Path.Combine(myPath, "ejv.json"))
is ok, while this
let data =
JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>
<| File.ReadAllText
<| Path.Combine(myPath, "ejv.json")
Gives me two errors, first is:
and second is:
What did I do wrong?
UPDATE @Patryk Ćwiek suggested a good edit, which seems to fix errors with types:
let data = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>
<< File.ReadAllText
<| Path.Combine(myPath, "ejv.json")
But it produces another puzzling message: Unexpected type arguments. Here's a screenshot:
I can easily get rid of it removing <Dictionary<string, Dictionary<string, string>>>
but in this case my data is of object
type, not a Dictionary
. Can I somehow save type information an use pipelining as well?
SOLUTION
Thanks to @Patryk Ćwiek solution is as follows:
let d<'a>(s:string) = JsonConvert.DeserializeObject<'a>(s)
let data =
Path.Combine(myPath, "ejv.json")
|> File.ReadAllText
|> d<Dictionary<string, Dictionary<string, string>>> with
I don't know why, but without that alias d
it doesn't work.
As far as I know, the evaluation goes from left to right, so your second expression is an equivalent of:
let data =
(JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>> <| File.ReadAllText)
<| Path.Combine(myPath, "ejv.json")
Notice how the operations flow. That means that you're passing a function to DeserializeObject
first, probably not what you meant to do.
When you do this:
let data =
JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>
<| (File.ReadAllText <| Path.Combine(myPath, "ejv.json"))
it will work. It's an equivalent of your first option.
Other solution is to invert piping to make the data flow more naturally:
let data = Path.Combine(myPath, "ejv.json")
|> File.ReadAllText
|> JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>
I've overlooked one option, that's not-so-commonly used. You can use function composition operator <<
to make it work, too:
let data = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>
<< File.ReadAllText
<| Path.Combine(myPath, "ejv.json")
It essentially combines DeserializeObject : string -> 'a
and ReadAllText : string -> string
into (unnamed in the example above) function f : string -> 'a
, where f(s) = DeserializeObject(ReadAllText(s))
. Then it feeds the result of Path.Combine
via pipe into f
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With