Hellow,
Aik Hui <[EMAIL PROTECTED]> writes:
I was trying to define a type class to overload a function with
more than type variable. ie
f :: Int -> Bool -> ...
f :: Bool -> Int -> ...
Can this be done in haskell?
Alastair Reid <[EMAIL PROTECTED]> :
Haskell won't let you define a type class which is parameterised
wrt more than one type variable.
However, you can define ordinary functions which are multiply
overloaded.
... (skipped)
You can even define member functions which are overloaded wrt other
type vars. For example, section 4.3.1 of the report contains this
example:
class Foo a where op :: Num b => a -> b -> a
which defines a member function with type:
op :: (Foo a, Num b) => a -> b -> a
------------------------------------------------------------------
------------------------------------------------------------------
After this, I try once more to imitate the multiparameter classes.
The problem is to model a class like
------------------------------------------------------------------
class (AdditiveGroup a, Field k) => VectorSpace a k where
cMul :: k -> a -> a
------------------------------------------------------------------
- "a group of vectors `a' is a vector space over a field `k' of
coefficients if there is given the multiplication by coefficient
(certain properties are presumed)".
As Haskell does not permit such a declaration, I try this:
------------------------------------------------------------------
class AdditiveGroup a => VectorSpace a where cMul:: k -> a -> a
------------------------------------------------------------------
- the question is what Haskell might think of this `k'.
Also the special data constructor is introduced which has the
_two_ parameters:
data VS a k = VS a k deriving(Text)
Semantics: VS v c is a vector over the coefficient instance to
which `c' belongs.
Further,
------------------------------------------------------------------
instance Eq a => Eq (VS a k) where (VS u _)==(VS v _) = u==v
...
instance Field a => VectorSpace (VS k k)
where
cMul c (VS v c') = VS (c*v) c'
-----------------------------------------------------------------
expresses quite naturally that any field (it should at least have
the (*) operation) can be viewed as a vector space over itself.
Similarly, we declare a 2-dimensional vector space instance for
(k,k) over k, and so on.
But ghc-0.29 (Haskell-1.2) reports
------------------------------------------------------------------
... Type signature mismatch:
Signature for class method `cMul' doesn't match its inferred type.
Signature: k._94 -> VS a._93 a._93 -> VS a._93 a._93
Inferred type: k._99 -> VS k._99 k._99 -> VS k._99 k._99
------------------------------------------------------------------
The class operation type k -> a -> a
is specialized to the instance where a === VS k k
In the class member declaration `k ' is a "free" variable.
Probably, Haskell understands this so, that any instance should
specify cMul for an instance of `a' _not_ tied to the instance
of `k'. Is this natural ?
Could anybody explain the Haskell idea on this case ?
Is ghc right ?
And what might be the way out ?
Thank you.
Sergey Mechveliani.
[EMAIL PROTECTED]