-
-
Notifications
You must be signed in to change notification settings - Fork 424
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
Arithmetic instances in LangaugeExt.TypeClass #1024
Comments
This sentence ^ confused me a bit, because instances shouldn't ever be C# doesn't have 'official' support for ad-hoc polymorphism (other than the static interface methods in the latest C#, but that hasn't any backward compatibility). However, there's a way to implement it by leveraging the fact that So, for example - this is a 'trait' or 'type-class' defined as an interface (sticking to monoid, as it's very simple): public interface Monoid<A>
{
A Empty();
A Append(A x, A y);
} Then the 'instance' can be implemented as a public struct MSeq<A> : Monoid<Seq<A>>
{
public Seq<A> Empty() => Seq<A>();
public Seq<A> Append(Seq<A> x, Seq<A> y) => x + y;
} If I do this: var mx = default(MSeq<int>); Then var xs = mx.Empty();
var ys = mx.Append(xs, Seq(1, 2, 3)); We don't ever pass instances around as data, we just need to provide them as generic arguments and constrain them. Here's a general example of public static A Append<MA, A>(A xs, A ys) where MA : struct, Monoid<A> =>
default(MA).Append(xs, ys); NOTE: The
Going back to this ^. I'm not sure what I wrote has clarified the fact that instances can't be
No, you must provide an instance that satisfies the maximum, or the "most powerful". I haven't worked with Scala, but that does sound a bit odd to me (accepting the least powerful). I'd always expect a constraint to want to be completely satisfied. I'm sure Haskell works that way (when explicitly stating the constraint, rather than letting the type-inference do it for you - in which case it would be the minimum). There's a write-up on the README about ad-hoc polymorphism in C#. Honestly, you might want to leave some of those generalist ideas in Scala-land, as it can get pretty ugly in C# (due to the lack of generic inference), and is definitely not idiomatic. However, it is type-safe, and it is legitimate ad-hoc polymorphism. Definitely forget the idea of trying to implement higher-kinds with it though, that's an ugly process. |
Agh, sorry that 'null' was a typo. That explanation is helpful though - does the I guess my confusion is that the public static A subtract<ARITH, A>(A x, A y) where ARITH : struct, Arithmetic<A> => default (ARITH).Subtract(x, y); Similarly, the I'm really still trying to find my way with the C# type system though so you're right there's probably a load of stuff I need to leave out of my thinking; I'll give the readme another look, thanks heaps :) |
No, structs (value types) are special in C#, they don’t have default ctors, they just zero the memory needed, which brings perf benefits for things like arrays of structs. In this case the compiler optimises away the struct allocation and just calls the methods direct (because there’s no fields, and are therefore zero size) You’re right that I should have used the more precise trait for subtract, and probably others. This is probably an artefact of me adding Num first and the other traits later. Feel free to open a PR if you’d fancy changing them. |
Ah I see, that makes sense. |
I'm pretty new to the library (really loving it 👌) and C# in general but I've come from a Scala Cats etc world so I'm not sure if I'm just trying to overlay what I've learned in that space too much and getting myself confused a bit.
I can see that
Arithmetic
defines thePlus
,Subtract
,Negate
andProduct
capabilities thatNum
extends from, I've got a custom data type that makes sense to have these implemented but not the rest of the methods thatNum
defines.I've tried to use the
subtract
etc static methods fromPrelude
but found that they expect a nullNum
instance:Should these methods accept an instance of
Arithmetic
as I think that's the "least powerful" typeclass that could be used?The text was updated successfully, but these errors were encountered: