这是Num类型类
type Num :: Type -> Constraint
class Num a where
(+) :: a -> a -> a
(*) :: a -> a -> a
-- .. I'm omitting the other methods
Run Code Online (Sandbox Code Playgroud)
这就是( src )Num的定义方式Int
instance Num Int where
(+) :: Int -> Int -> Int
I# x + I# y = I# (x +# y)
(*) :: Int -> Int -> Int
I# x * I# y = I# (x *# y)
-- ..
Run Code Online (Sandbox Code Playgroud)
这就是它的定义方式Float( src )
instance Num Float where
(+) :: Float -> Float -> Float
F# x + F# y = F# (plusFloat# x y)
(*) :: Float -> Float -> Float
F# x * F# y = F# (timesFloat# x y)
Run Code Online (Sandbox Code Playgroud)
也许没有启发性,但您可以看到(对于这些实例)它们是根据(+#)or等原始操作定义的timesFloat#。如果您定义自己的数字,则可以根据重复加法来定义乘法,但运算基本上不是这样定义的。
type N :: Type
data N = O | S N
instance Num N where
(+) :: N -> N -> N
O + m = m
S n + m = S (n + m)
(*) :: N -> N -> N
O * _ = O
S n * m = m + (n * m)
Run Code Online (Sandbox Code Playgroud)
您可以定义一个“默认”乘法函数,该函数是根据重复加法定义的
-- >> timesViaPlus @Int @Int 10 20
-- 200
-- >> timesViaPlus @Integer @Integer 10 20
-- 200
timesViaPlus :: Integral n => Num m => n -> m -> m
timesViaPlus n m = sum (fromIntegral n `replicate` m)
Run Code Online (Sandbox Code Playgroud)
或者您可以将其专门化N并使用它来定义(*) @N.
replicateN :: N -> a -> [a]
replicateN O _ = []
replicateN (S n) a = a : replicateN n a
timesViaPlusN :: Num n => N -> n -> n
timesViaPlusN n m = sum (n `replicateN` m)
instance Num N where
(+) :: N -> N -> N
O + m = m
S n + m = S (n + m)
(*) :: N -> N -> N
(*) = timesViaPlusN
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
174 次 |
| 最近记录: |