> My problem:
> ----------
> One of the algorithms I have to implement is the
> addition of symbolic expressions. It should have
> two symbolic expressions as arguments and should
> produce a symbolic expression as the result. But
> how the result is produced is depending on series
> of flags that control how the expressions is to
> be manipulated. This set of flags should then be
> passed as a third argument to addition function.
> This is the correct way of doing it. But, being
> a Mathematics application, my system should preserve
> the tradicional Math notation (that is, infix
> operators with suitable associations defined). So
> my symbolic expression type should be an instance
> of the Num class so that the (+) operator can
> be overloaded for it. But, as the function has
> now three arguments, it cannot be a binary operator
> anymore.

There are no problems in having infix operators with more than two
parameters, eg. the operators `plus` and `times` below both take a third
parameter:

  infixl 6 `plus`
  infixl 7 `times`

  int :: Int->(Int->Int)
  int n x = n

  x :: (Int->Int)
  x y = y

  plus :: (Int->Int)->(Int->Int)->(Int->Int)
  (a `plus` b) x = a x + b x

  times :: (Int->Int)->(Int->Int)->(Int->Int)
  (a `times` b) x = a x * b x

This allows for expressions such as (x `times` (int 1 `plus` x)) 7 that
evaluates to 56.  Replacing + and * for `plus` and `times`, that is
making (a suitable newtype over) Int->Int into an instance of Num is
more or less trivial - except for some silly choices when making the Eq
instance:  Whether expressions of this type are equal should probably
depend on the environment.  But as the return type of == is Bool the
environment will not be available and you would have to make == a dummy
function.  In fact you would probably be better of by hiding the prelude
and overloading + and friends on your own.

Michael Florentin Nielsen ([EMAIL PROTECTED])

Reply via email to