title: Modeling exchange in Haskell
body: <p>I'm new to Haskell, and I'm looking to model stock exchange library. It's meant to be a library, hence specifics to be defined by the user. The way I intend to use this is to have users define things like this. </p>
  
  <pre><code>data MyExchange = MyExchange { name :: ExchangeName
                               , base :: Currency
                               , quote :: Currency }
                               deriving (Eq, Show)
  
  instance Exchange MyExchange
  
  data MyExchangeBookMessage = 
          MyExchangeBookMessage { time :: Time
                                , exchange :: MyExchange
                                , price :: Price 
                                , side :: Side
                                , amount :: Maybe Amount }
                                deriving (Eq, Show)
  
  instance ExchangeBookMessage MyExchangeBookMessage
  </code></pre>
  
  <p>I've tried the following, but immediately ran into some limitations of type classes. Below is the code and the error message. Specifically what are the alternatives to parameterizing type classes with multiple types?</p>
  
  <p>Here is the code for the library</p>
  
  <pre><code>module Lib where
  
  data Side = Buy | Sell deriving (Eq, Show)
  
  newtype Amount = Amount Rational deriving (Eq, Show)
  
  newtype Price = Price Rational deriving (Eq, Show)
  
  newtype Currency = Currency String deriving (Eq, Show)
  
  newtype Time = Time Integer deriving (Eq, Show)
  
  type ExchangeName = String
  
  class Exchange a where
    name :: a -&gt; ExchangeName
    base :: a -&gt; Currency
    quote :: a -&gt; Currency
  
  
  class Message a where
    time :: a -&gt; Time
  
  class (Message a, Exchange e) =&gt; ExchangeMessage a e where
    exchange :: a -&gt; e
  
  class ExchangeMessage a b =&gt; BookMessage a b where
    price :: a -&gt; Price
    side :: a -&gt; Side
    amount :: a -&gt; Maybe Amount
  </code></pre>
  
  <p>And the error message:</p>
  
  <pre><code>src/Lib.hs:22:1: error:
      • Too many parameters for class ‘ExchangeMessage’
        (Use MultiParamTypeClasses to allow multi-parameter classes)
      • In the class declaration for ‘ExchangeMessage’
  </code></pre>
  
  <p>Later I would like to be able to implement type classes like this:</p>
  
  <pre><code>class Strategy s where
    run (Message m, Action a) =&gt; s -&gt; m -&gt; a
  </code></pre>
  
  <p>In the <code>Strategy</code> implementations the <code>run</code> function will take an abstract message m, pattern match it against relevant <code>Message</code> data constructors and return specific action.</p>
  
  <p>I'm porting some Scala code. in Scala I was using a hierarchy of traits with concrete case classes at the bottom:</p>
  
  <pre><code>trait Exchange { 
    def name: String
    def base: Currency
    def quote: Currency 
  }
  
  case class MyExchange(base: Currency, quote: Currency) {
    val name = "my-exchange"
  }
  
  trait Message {
    def time: Long
  }
  
  trait ExchangeMessage extends Message {
    def exchange: Exchange
  }
  
  trait BookMessage extends ExchangeMessage {
    def price: Double
    def side: Side
    def amount: Option[Double]
  }
  
  case class MyBookMessage(time: Long, price: Double, side: Side, amount: Option[Double]) {
    def exchange: Exchange = MyExchange(...)
  }
  </code></pre>