Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Util.Table broken for anonymous records #233

Open
rudihorn opened this issue Jun 28, 2019 · 4 comments
Open

Util.Table broken for anonymous records #233

rudihorn opened this issue Jun 28, 2019 · 4 comments

Comments

@rudihorn
Copy link
Contributor

Description

This seems to more be an F# bug related to a unification error with F# anonymous record types (possibly a dotnet restriction?).

Repro steps

[ {|id=5; name = "hello"|} ] |> Util.Table

Expected behavior

Table output

Actual behavior

Error message:

Type constraint mismatch. The type
'{|id : int ; name : string|} list'
is not compatible with type
'seq<{|id : int ; name : string|}>'

Known workarounds

Define it within a module:

open System

module MUtil =
    let Row (columns:seq<Reflection.PropertyInfo>) (item:'A) =
        columns
        |> Seq.map (fun p -> p.GetValue(item))
        |> Seq.map Convert.ToString
        |> Seq.toArray

    let Table (items:seq<'A>, propertyNames:seq<string> option) =
        let properties = 
            if propertyNames.IsSome then
                typeof<'A>.GetProperties()
                |> Seq.filter (fun x -> (propertyNames.Value |> Seq.exists (fun y -> x.Name = y)))
                |> Seq.toArray
            else
                typeof<'A>.GetProperties()
        { 
            Columns = properties |> Array.map (fun x -> x.Name);
            Rows = 
                items 
                |> Seq.map (Test.MyRow properties)
                |> Seq.toArray
        }
    
    let DefaultTable items = Table (items, None)

Then call:

[ {|id=5; name = "hello"|} ] |>  MUtil.DefaultTable

Related information

  • Operating system: Ubuntu
  • Branch: Master
  • CoreCLR
@rudihorn
Copy link
Contributor Author

Questions I still have:

  • Is this a dotnet core issue?
  • Is this issue known and tracked?
  • Is it worth trying to issue a workaround and switch to an F# module in IfSharp

@cgravill
Copy link
Member

It's not a .NET Core issue.

I'd be tempted to just initialise as a seq or convert to that:

[ {|id=5; name = "hello"|} ] |> Seq.ofList |> Util.Table

but improving compatibility seems like a good idea too.

@cgravill
Copy link
Member

To confirm the implicit conversion works for explict records:

image

static member Table (items:seq<'A>, ?propertyNames:seq<string>) =
// get the properties
let properties =
if propertyNames.IsSome then
typeof<'A>.GetProperties()
|> Seq.filter (fun x -> (propertyNames.Value |> Seq.exists (fun y -> x.Name = y)))
|> Seq.toArray
else
typeof<'A>.GetProperties()
{
Columns = properties |> Array.map (fun x -> x.Name);
Rows = items |> Seq.map (Util.Row properties) |> Seq.toArray;
}

@rudihorn
Copy link
Contributor Author

To confirm the implicit conversion works for explict records:

image

static member Table (items:seq<'A>, ?propertyNames:seq<string>) =
// get the properties
let properties =
if propertyNames.IsSome then
typeof<'A>.GetProperties()
|> Seq.filter (fun x -> (propertyNames.Value |> Seq.exists (fun y -> x.Name = y)))
|> Seq.toArray
else
typeof<'A>.GetProperties()
{
Columns = properties |> Array.map (fun x -> x.Name);
Rows = items |> Seq.map (Util.Row properties) |> Seq.toArray;
}

Yes this is what was confusing me about this. The conversion to a seq first works for me though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants