Я новичок в Haskell, и я ищу модель фондовой биржи. Он предназначен для библиотеки, поэтому специфика должна определяться пользователем. Способ, которым я намереваюсь использовать это, состоит в том, чтобы пользователи определяли такие вещи.Обмен моделями в Haskell
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
Я пробовал следующее, но сразу же столкнулся с некоторыми ограничениями классов типов. Ниже приведен код и сообщение об ошибке. В частности, каковы альтернативы параметризации классов типов с несколькими типами?
Вот код для библиотеки
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 -> ExchangeName
base :: a -> Currency
quote :: a -> Currency
class Message a where
time :: a -> Time
class (Message a, Exchange e) => ExchangeMessage a e where
exchange :: a -> e
class ExchangeMessage a b => BookMessage a b where
price :: a -> Price
side :: a -> Side
amount :: a -> Maybe Amount
и сообщение об ошибке:
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’
Позже я хотел бы быть в состоянии реализовать классы типа, как это:
class Strategy s where
run (Message m, Action a) => s -> m -> a
В реализациях Strategy
функция run
примет абстракцию t сообщение m, шаблон сопоставляет его с соответствующими конструкторами данных Message
и возвращает определенное действие.
Я портирую код Scala. в Scala я использовал иерархию черт с конкретными классами случае в нижней части:
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(...)
}
Существует предложение «Использовать MultiParamTypeClasses, чтобы разрешить многопараметрические классы», я предлагаю вам его взять. Поместите '{- # LANGAUGE MultiParamTypeClasses # -}' в первую строку файла, чтобы включить его. – luqui
Это будет «работать», но вы столкнетесь с другими проблемами при попытке использовать любые методы «BookMessage». Я не уверен, что 'b' должен быть там ... – luqui
@luqui:' BookMessage' расширяет 'ExchangeMessage':' b' - это тип 'Exchange', который поступает из' ExchangeMessage'. –