I have a type
class IntegerAsType a where
value :: a -> Integer
data T5
instance IntegerAsType T5 where value _ = 5
newtype (Num a, IntegerAsType n) => PolyRing a n = PolyRing [a]
My main question is: how do I define a variable in a particular PolyRing?
It should be something like:
x = [1, 2, 3] :: Integer T5
(I think)
The question is: what is the correct syntax after the ::?
I'm getting the error
Couldn't match expected type `PolyRing Integer T5'
with actual type `[t0]'
In the expression: [1, 2, 3] :: PolyRing Integer T5
In an equation for `x': x = [1, 2, 3] :: PolyRing Integer T5
Also, I'm looking for a better way to implement this. In particular, I'd really like for the type a to be inferred from the type of list elements, while the IntegerAsType n must be specified (it shouldn't depend on the length of the list, even if that is possible).
Things I've tried so far:
x = [1,2,3] :: PolyRing (Integer, T5)
x = [1,2,3] :: PolyRing Integer T5
First Note
Data type contexts, such as:
newtype (Num a, IntegerAsType n) => PolyRing a n = PolyRing [a]
are generally a bad idea and have been retired from the language.
Ignoring That
To construct an instance you must use the data constructor PolyRing:
PolyRing [1,2,3]
But that isn't enough, the type inference so far will be (IntegerAsType n) => PolyRing Integer n. Your final type signature would finish this up let x = PolyRing [1,2,3] :: PolyRing Integer T5.
Returning To the First Note
Still, perhaps you wanted:
newtype PolyRing a n = PolyRing [a]
And every function that builds or consumes a polyring can enforce the needed constraints:
func :: (Num a, IntegerAsType n) => PolyRing a n -> ...
A newtype is not just a synonym but a way to create a type that is distinct at the type level (though identical later). That said - you need to wrap it explicitly using your data constructor. Also, the context has no effect. You still have to type it everywhere.
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