Haskell 运算符 * 是 + 运算符的组合吗?

Con*_*nor 1 haskell operators

Haskell 是如何*工作的?它会创建一系列+运算符,还是会执行其他操作?

Ice*_*ack 9

这是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)