<br><font size=2 face="sans-serif">Dear Haskell,</font>
<br>
<br><font size=2 face="sans-serif">Most of the time we get along well.
&nbsp;But, I'm growing weary of the arguments, fights, and nitpicking when
I try to implement new mathematical types and overload your operators.
&nbsp;I don't know how to cooperate with your type systems. &nbsp;At moments
like this, I think about getting back together with C++.</font>
<br>
<br><font size=2 face="sans-serif">I love you. &nbsp;But, I also love implementing
complex numbers, vectors, matrices, and quaternions, and Galois fields.
&nbsp;C++ is not nearly as elegant and beautiful as you. &nbsp;But, C++
doesn't complain when I try to do this. &nbsp;Isn't there some way we can
work things out so I can implement these types with you?</font>
<br>
<br><font size=2 face="sans-serif">Seriously, I'm trying to implement a
vector. &nbsp;I'm starting with vector addition:</font>
<br>
<br><font size=2 face="Courier New">{-</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp;This code is works with
Glasgow, ghci, with these options:</font>
<br><font size=2 face="Courier New">&nbsp; -fglasgow-exts</font>
<br><font size=2 face="Courier New">&nbsp; -fallow-undecidable-instances</font>
<br><font size=2 face="Courier New">&nbsp; -fno-monomorphism-restriction</font>
<br><font size=2 face="Courier New">&nbsp; -fallow-incoherent-instances</font>
<br><font size=2 face="Courier New">-}</font>
<br>
<br><font size=2 face="Courier New">data Vector a = Vector [a] deriving
Show</font>
<br>
<br><font size=2 face="Courier New">class Add a b c | a b -&gt; c where</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp;(.+) :: a -&gt; b -&gt;
c</font>
<br>
<br><font size=2 face="Courier New">instance Add Int Int Int where</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp;(.+) x y = x + y</font>
<br>
<br><font size=2 face="Courier New">instance Add Int Double Double where</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp;(.+) x y = (fromIntegral
x) + y</font>
<br>
<br><font size=2 face="Courier New">instance Add Double Int Double where</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp;(.+) x y = x + (fromIntegral
y)</font>
<br>
<br><font size=2 face="Courier New">instance Add Double Double Double where</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp;(.+) x y = x + y</font>
<br>
<br>
<br><font size=2 face="Courier New">instance (Add a b c) =&gt; Add (Vector
a) (Vector b) (Vector c) where</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp;(.+) (Vector x) (Vector
y) = Vector (zipWith (.+) x y)</font>
<br>
<br><font size=2 face="Courier New">vi1 = Vector [(1::Int)..3]</font>
<br><font size=2 face="Courier New">vi2 = Vector [(10::Int),15,2]</font>
<br><font size=2 face="Courier New">vd1 = Vector [(1::Double)..3]</font>
<br><font size=2 face="Courier New">vd2 = Vector [(10::Double),15,2]</font>
<br><font size=2 face="Courier New">test1 = vi1 .+ vi2</font>
<br><font size=2 face="Courier New">test2 = vi1 .+ vd2</font>
<br><font size=2 face="Courier New">test3 = vd1 .+ vi2</font>
<br><font size=2 face="Courier New">test4 = vd1 .+ vd2</font>
<br>
<br><font size=2 face="Courier New">v1 = Vector [1,2,3]</font>
<br><font size=2 face="Courier New">v2 = Vector [10,15,2]</font>
<br>
<br>
<br><font size=2 face="sans-serif">However, it is necessary to explicitly
nail down the type of the Vector. &nbsp;v1 and v2 are more general.</font>
<br>
<br><font size=2 face="Courier New">*Main&gt; :t v1</font>
<br><font size=2 face="Courier New">v1 :: forall a. (Num a) =&gt; Vector
a</font>
<br><font size=2 face="Courier New">*Main&gt; :t v2</font>
<br><font size=2 face="Courier New">v2 :: forall a. (Num a) =&gt; Vector
a</font>
<br><font size=2 face="Courier New">*Main&gt; test2</font>
<br>
<br><font size=2 face="sans-serif">I'd like for .+ to work with v1 and
v2. &nbsp;So, I can use things like Vector [1,2,3] in expressions, instead
of Vector[(1::Int),2,3]. &nbsp;However, v1 and v2 do not work with .+ in
the code I produced above.</font>
<br>
<br><font size=2 face="sans-serif">Does anyone have any ideas how to make
this work? &nbsp;I hoped defining .+ more generally for instances of Num
would make my vector addition code work with v1 and v2. &nbsp;My failed
attempt involved making the following changes . . .</font>
<br>
<br><font size=2 face="Courier New">-- I added this</font>
<br><font size=2 face="Courier New">instance (Num d) =&gt; Add d d d where</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp;(.+) x y = x + y</font>
<br>
<br><font size=2 face="Courier New">-- instance Add Int Int Int where</font>
<br><font size=2 face="Courier New">-- &nbsp; &nbsp;(.+) x y = x + y</font>
<br>
<br><font size=2 face="Courier New">instance Add Int Double Double where</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp;(.+) x y = (fromIntegral
x) + y</font>
<br>
<br><font size=2 face="Courier New">instance Add Double Int Double where</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp;(.+) x y = x + (fromIntegral
y)</font>
<br>
<br><font size=2 face="Courier New">-- instance Add Double Double Double
where</font>
<br><font size=2 face="Courier New">-- &nbsp; &nbsp;(.+) x y = x + y</font>
<br>
<br><font size=2 face="sans-serif">When I make these changes and compile,
I get the following error messages on the declaration of test1 and test4.
. .</font>
<br>
<br><font size=2 face="Courier New">Vector2.hs:38:12:</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; Overlapping instances
for Add (Vector Int) (Vector Int) (Vector Int)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; arising from use
of `.+' at Vector2.hs:38:12-13</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; Matching instances:</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; Vector2.hs:31:0:
instance (Add a b c) =&gt; Add (Vector a) (Vector b) (Vector c)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; Vector2.hs:15:0:
instance (Num d) =&gt; Add d d d</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; In the definition of
`test1': test1 = vi1 .+ vi2</font>
<br>
<br><font size=2 face="Courier New">Vector2.hs:41:12:</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; Overlapping instances
for Add (Vector Double) (Vector Double) (Vector Double)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; arising from use
of `.+' at Vector2.hs:41:12-13</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; Matching instances:</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; Vector2.hs:31:0:
instance (Add a b c) =&gt; Add (Vector a) (Vector b) (Vector c)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; Vector2.hs:15:0:
instance (Num d) =&gt; Add d d d</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; In the definition of
`test4': test4 = vd1 .+ vd2</font>
<br>
<br><font size=2 face="sans-serif">I interpret this as saying that the
compiler doesn't know if the .+ in &quot;test1 = vi1 .+ vi2&quot; should
match the Vector instance or the Num instance. &nbsp;I could understand
this if Vector was an instance of class Num. &nbsp;However, this is not
the case. &nbsp;I figure either Glasgow has a bug or I don't really understand
the error message.</font>
<br>
<br><font size=2 face="sans-serif">I'd be grateful for any suggestions
or pointers to information on how to implement vectors (or other mathematical
types) so they seamlessly and intuitively work with types, classes and
operators already built into Haskell. &nbsp;Or, if someone could point
to a more intermediate level book on working with the Haskell type system,
that would be great. &nbsp;</font>
<br>
<br>
<br>
<br>