Closed bradphelan closed 6 years ago
I tried
public class ContainerOrderingTests
{
public class WithSet : Record<WithSet>
{
public WithSet(int i, Set<OrdInt,int> s)
{
I = i;
S = s;
}
public int I { get; }
public Set<OrdInt,int> S { get; }
}
[Fact]
public void SetOrderingWorks()
{
var a = new WithSet(0, Prelude.Set<OrdInt,int>(0,1,2));
var b = new WithSet(0, Prelude.Set<OrdInt,int>(0,1,2));
Assert.Equal(0,a.CompareTo( b )) ;
}
}
but I think that is really just the same as the first example
Progress. I now have
/// <summary>
/// The pattern we are trying to match here is
/// <![CDATA[M<N<T>>]]>
/// which for examples models <![CDATA[Ord<Set<T>>]]>
/// The generated type needs to match <![CDATA[MN<MT,T>]]>
/// or for our concrete example <![CDATA[OrdSet<OrdInt,Int32>]]>
/// </summary>
/// <returns></returns>
public static Option<Type> GetOrderableContainerOrd()
{
Option<TypeInfo> ArityOneGeneric(TypeInfo baseInfo)
{
return baseInfo.GenericTypeArguments == null || baseInfo.GenericTypeArguments.Length != 1
? (Option<TypeInfo>) None
: baseInfo.GenericTypeArguments[0].GetTypeInfo();
}
string RemoveGenerics(string name) => FirstCharToUpper(OrdNameMaps(name.Split( '`' ).Head()));
var mType = typeof(A).GetTypeInfo();
return
from nType in ArityOneGeneric( mType )
from tType in ArityOneGeneric( nType )
let mnTypeName = RemoveGenerics( mType.Name ) + RemoveGenerics( nType.Name ) + "`2"
let mtTypeName = RemoveGenerics( mType.Name ) + RemoveGenerics( tType.Name )
let tTypeName = RemoveGenerics( tType.Name )
from mnType in ClassInstancesAssembly.Structs.Where( t => t.Name == mnTypeName ).HeadOrNone()
from ntType in ClassInstancesAssembly.Structs.Where( t => t.Name == mtTypeName ).HeadOrNone()
select mnType.MakeGenericType( ntType, tType );
}
static string OrdNameMaps(string typename)
{
switch (typename)
{
case "Int32": return "Int";
case "Int64": return "Long";
default: return typename;
}
}
public static string FirstCharToUpper(string input)
{
switch (input)
{
case null: throw new ArgumentNullException(nameof(input));
case "": throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input));
default: return input.First().ToString().ToUpper() + input.Substring(1);
}
}
which can resolve the test
[Fact]
public void GetOrderableContainerOrderWorks()
{
var type = Class<Ord<Set<int>>>.GetOrderableContainerOrd();
Assert.True( type.IsSome );
}
@bradphelan Hi Brad, I've been away for a week or so, so I'll take a look at this once my head is back in gear.
@bradphelan Hi Brad, sorry for the delay. Map<K,V>
, Map<OrdK, K, V>
, Set<A>
, Set<OrdA, A>
, Lst<A>
, Lst<PredA, A>
, Lst<PredList, PredItem, A>
now all support IComparable
as well as the <
, <=
, >=
, >
operators. So your records should also use those.
Super :)
On Tue, 14 Nov 2017, 16:32 Paul Louth notifications@github.com wrote:
@bradphelan https://github.com/bradphelan Hi Brad, sorry for the delay. Map<K,V>, Map<OrdK, K, V>, Set, Set<OrdA, A>, Lst, Lst<PredA, A>, Lst<PredList, PredItem, A> now all support IComparable as well as the <, <=, >=, > operators
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/louthy/language-ext/issues/293#issuecomment-344295849, or mute the thread https://github.com/notifications/unsubscribe-auth/AABE8gMYcBt5c1B5KXjJ34w44brdHH8Yks5s2bJygaJpZM4QD4ND .
I have the following test
which fails with the fact that Set does not implement IComparable. But somehow I'm sure you have thought of this but the solution is non obvious.