Coerce to multiple-parameter type in Haskell
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 th开发者_JAVA技巧e 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.
精彩评论