我编写了一个类型类,以避免为不同类型编写重复函数,如下所示:
import Statistics.Distribution.Normal
import Data.Random
d1 :: Double -> Double -> Double -> Double -> Double -> Double
d1 s k r v t = ( log ( s / k ) + ( ( v * v ) / 2 ) * t ) / ( v * sqrt t )
d2 :: Double -> Double -> Double -> Double -> Double -> Double
d2 s k r v t = d1 s k r v t - v * sqrt t
call :: Double -> Double -> Double -> Double -> Double -> Double
call s k r t v = exp ( -r * t ) * ( s * cdf normal ( d1 s k r v t )
- k * cdf normal ( d2 s k r v t ) )
where normal = Normal (0 :: Double) 1
put :: Double -> Double -> Double -> Double -> Double -> Double
put s k r t v = exp ( -r * t ) * ( k * cdf normal ( - d2 s k r v t )
- s * cdf normal ( - d1 s k r v t ) )
where normal = Normal (0 :: Double) 1
class Black a where
price :: a -> Double -> Double -> Double
instance Black ( Option Future ) where
price ( Option ( Future s ) Call European k t ) r v = call s k r t v
price ( Option ( Future s ) Put European k t ) r v = put s k r t v
instance Black ( Option Forward ) where
price ( Option ( Forward s ) Call European k t ) r v = call s k r t v
price ( Option ( Forward s ) Put European k t ) r v = put s k r t v
这是类型类的有效使用吗?我问的原因是我没有为任何给定类型重载价格函数的定义。我所做的就是避免写作:
priceFuture :: (Option Future) -> Double -> Double -> Double
// impl
priceFoward :: (Option Forward) -> Double -> Double -> Double
impl
data Option a = Option a Type Style Strike Expiration deriving (Show)
data Future = Future Price deriving (Show)
data Forward = Forward Price deriving (Show)
type Barrier = Double
type Expiration = Double
type Price = Double
type Strike = Double
type Value = Double
type Dividend = Double
type Rate = Double
data Type = Call | Put deriving (Eq, Show)
data Style = European | American deriving (Eq, Show)
答案 0 :(得分:5)
我想我只是让Option
的论证成为幻影类型:
data Option a = Option Price Type Style Strike
data Future
data Forward
price :: Option a -> Double -> Double -> Double
price (Option s Call European k t) r v = call s k r t v
price (Option s Put European k t) r v = put s k r t v
重复次数少得多,并且不需要类型类,但如果您需要其他选项,您仍然会在前向选项(Option Forward
)和将来的选项(Option Future
)之间获得类型级别的区别。如果您真的很兴奋,可以打开DataKinds
以确保Future
和Forward
是Option
唯一两个可能的类型级参数。
答案 1 :(得分:1)
这个怎么样?
data Option = Option ForFut Type Style Strike Expiration deriving (Show)
data ForFut = Forward Price | Future Price deriving (Show)
type Barrier = Double
type Expiration = Double
type Price = Double
type Strike = Double
type Value = Double
type Dividend = Double
type Rate = Double
data Type = Call | Put deriving (Eq, Show)
data Style = European | American deriving (Eq, Show)
call :: Double -> Double -> Double -> Double -> Double -> Double
call = undefined
put :: Double -> Double -> Double -> Double -> Double -> Double
put = undefined
price :: Option -> Double -> Double -> Double
price ( Option ( Future s ) Call European k t ) r v = call s k r t v
price ( Option ( Future s ) Put European k t ) r v = put s k r t v
price ( Option ( Forward s ) Call European k t ) r v = call s k r t v
price ( Option ( Forward s ) Put European k t ) r v = put s k r t v
因此,我将Forward
和Future
类型合并为一种类型。这样就无需使Option
成为更高级的类型。然后可以删除类型类,并且可以使用简单的模式匹配来定义price
。