question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

query expression with group by and Validation does not work

See original GitHub issue

Hello Louthy and All, I have a query expression that works for data as an Option but when I try to do the same query as a Validation it does not work.

Here is the case that works as an option:

public static Func<IEnumerable<Option<CellData>>, IEnumerable<Finding>>
            GetAndMergeDbValues = cells =>
            {
                var groupings = from opt in cells
                                from c in opt
                                group c by (c.TimePeriod, c.Periodicity) into g
                                select new QueryGrouping
                                (
                                    g.Key.Item1,
                                    g.Key.Item2,
                                    g
                                );

                ...
            };

The ctor and data CellData is defined as:

public class CellData
    {
        public CellData(string sheet,
                        string range,
                        string companyId,
                        string mnemonic,
                        DateTime timePeriod,
                        string periodicity,
                        string value)
        {
            this.Sheet = sheet;
            this.Range = range;
            this.CompanyId = companyId;
            this.Mnemonic = mnemonic;
            this.TimePeriod = timePeriod;
            this.Periodicity = periodicity;
            this.Value = value;
        }

Left out private static constructors methods for brevity’s sake.

Finally QueryGrouping is defined as:

public class QueryGrouping
    {
        public QueryGrouping(DateTime TimePeriod, string Periodicity, IEnumerable<CellData> Cells)
        {
            this.TimePeriod = TimePeriod;
            this.Periodicity = Periodicity;
            this.Cells = Cells;
        }

        public string Periodicity { get; set; }

        public DateTime TimePeriod { get; set; }

        public IEnumerable<CellData> Cells { get; set; }
    }

Now if i change my function to use validation it looks like this:

public static Func<IEnumerable<Validation<string, CellData>>, IEnumerable<Finding>>
            GetAndMergeDbValues = cells =>
            {
                var groupings = from opt in cells
                                from c in opt
                                group c by (c.Success.TimePeriod, c.Success.Periodicity) into g
                                select new QueryGrouping
                                (
                                    g.Key.Item1,
                                    g.Key.Item2,
                                    g
                                );
                ...
            };

I presume I have to explicitly call Success on c because it has two states?

Also I get an error on the contructor of query grouping that it expects IEnumerable<CellData> and I’m passing IEnumerable<Validation<string, CellData>>.

I would expect the Select definition for Validation to only return the good state since this is monadic flow.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:21 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
TysonMNcommented, Feb 6, 2019
IEnumerable<Seq<string>> errors = cells
  .Map(v => v.Match(_ => None, Some))
  .Somes();
1reaction
TysonMNcommented, Feb 5, 2019

I think I understand your problem. First, I will share my suggestion and then explain why you were having trouble.

Suggestion

In the Option<> case, I recommend this code:

var groupings = cells
    .Somes()
    .GroupBy(c => (c.TimePeriod, c.Periodicity))
    .Map(g => new QueryGrouping(
        g.Key.Item1,
        g.Key.Item2,
        g));

Then in the Validation<,> case, I recommend reducing to the Option<> case with this code:

var groupings = cells
    .Map(val => val.ToOption())
    .Somes()
    .GroupBy(c => (c.TimePeriod, c.Periodicity))
    .Map(g => new QueryGrouping(
        g.Key.Item1,
        g.Key.Item2,
        g));

Explanation

I would expect the Select definition for Validation to only return the good state since this is monadic flow.

That is true, but the code in your example is not calling Validation<,>.Select; it is calling IEnumerator<ValidationData<,>>.GetEnumerator, which is defined on IEnumerable<ValidationData<,>>.

Each LINQ syntax query can only “unwrap” a single monad (or, more generally, functor). In both of your examples, the single functor in question is IEnumerable<>. Both Option<> and Validation<,> implement IEnumerable<T> for some type T. For Option<A>, we have T = A. For Validation<F, S>, we have T = ValidationData<F, S>. Enumerating over an Option<A> will yield an A it if has one and nothing otherwise. Enumerating over Validation<F, S> will yield exactly one ValidationData<F, S> in the appropriate state and containing the corresponding data.

I presume I have to explicitly call Success on c because it has two states?

Sort of, but the Success property could contain garbage data if the ValidationData<,> instance is in the other state.

By looking at your code, I think you are trying to filter out the instances of Option<> and Validation<,> that are not in the “good” state and then mapping the remaining CellData instances to QueryGrouping instances. (In particular for your Option<> case, you start with cells of type IEnumerable<Option<CellData>> and end with groupings of type IEnumerable<QueryGrouping>.) That is exactly what my suggestions do.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Snowflake: "SQL compilation error:... is not a valid group by ...
The reason is that the window function is parsed "after" the group by , and there is no product_id or retail_price after the...
Read more >
How to Fix a 'Not a GROUP BY Expression' Error
If you try to run this query, the Oracle database will output the following error message: ORA-00979: not a GROUP BY expression.
Read more >
MySQL
We get many questions on how to solve query failures regarding ONLY_FULL_GROUP_BY SQL Mode after upgrading MySQL. Here's how to fix it.
Read more >
Fix SQL Error 'is not a valid GROUP BY expression' in ...
is not a valid group by expression." In this example, the error is produced because there's been an aggregation function added in the...
Read more >
Query expression basics (LINQ in C#)
A query is a set of instructions that describes what data to retrieve from a given data source (or sources) and what shape...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found