I've defined a newtype called Poly. Poly is a list representation of a polynomial (a list of Num's), and I'm trying to define a function "chop" that takes off excess 0's from the end of a Poly.
Chop takes one Poly as an argument, and then returns a Poly. For some reason I'm getting the following error message:
Expected a constraint, but ‘Poly a’ has kind ‘*’ In the type signature for ‘chop’: chop :: Poly a => a -> a
newtype Poly a = P [a]
chop :: Poly a => a -> a
chop l = if (last l) == 0 then chop (init l) else l
In Haskell, the =>
character in a type signature denotes a type restriction. This is used in conjunction with Haskell typeclasses in order to abstract away implementation details about functions that can be used at a high level of abstraction.
In your example, Poly a
is a completely new type according to the type system, not a typeclass, so your function chop
likely is intended to operate on it directly:
chop :: Poly a -> Poly a
chop (P l) = if (last l) == 0 then chop (P $ init l) else P l
But wait, this doesn't compile! The restriction comes from the comparison to 0: (last l) == 0
. Here we're implicitly saying that we want the elements of our Poly a
to be comparable to zero, or in other words a
must be an instance of Num a
. After all, you wouldn't be able to chop a polynomial of type Poly (Maybe String)
. Our revised type signature is:
chop :: Num a => Poly a -> Poly a
chop (P l) = if (last l) == 0 then chop (P $ init l) else P l
One thing to take into consideration: because you are using a newtype
and not a plain old type
, Haskell is treating your Poly a
as a completely new type. In order to make it interchangeable with lists, you can use a type synonym:
type Poly a = [a]
This will simplify the implementation of chop:
chop :: Num a => Poly a -> Poly a
chop l = if (last l) == 0 then chop (init l) else l