我习惯使用%来表示其他语言中的“modulo”。在Haskell中,我们必须使用mod x y
或x `mod` y
。那么,Haskell中使用的这个符号是什么?
在Haskell中,我们可以像普通函数一样定义具有各种符号(包括%
)的二元运算符。因此,您可以将%
定义为您想要的任意运算符(在您定义它的模块中)。
作为最典型的情况,%
是由Ratio
提供的Data.Ratio module类型的构造函数。
尝试下面的GHCi代码,以确保%
由Data.Ratio
提供:
ghci> 3 % 9
<interactive>:1:3: error:
Variable not in scope: (%) :: Integer -> Integer -> t
ghci> import Data.Ratio
ghci> 3 % 9
1 % 3
请记住,您可以在这些搜索引擎中搜索此类运算符和函数:
实际上我已经查明了%
如何定义Hoogle。
%是定义为的中缀函数
(%) :: Integral a => a -> a -> Ratio a
从上面的类型定义,你可以看到它是Data.Ratio
库的一部分,它主要处理比率(即:分数)。它的代码是
x % y = reduce (x * signum y) (abs y)
因此给定两个积分(x,y),它返回不可约分数x / y
快速查看Hoogle,您可以看到%
是一个定义为的中缀函数
(%) :: Integral a => a -> a -> Ratio a
并且你可以猜测它是Data.Ratio
库的一部分,它主要处理比率(即:分数)。这是代码
x % y = reduce (x * signum y) (abs y)
因此给定两个积分(x,y),它返回不可约分数x / y
Searching for (%)
on Stackage Hoogle,似乎Data.Ratio
将%
算子定义为从分子和分母构造Ratio
值。一个GHCi的例子:
Prelude> :m + Data.Ratio
Prelude Data.Ratio> let x = 1 % 2
Prelude Data.Ratio> x
1 % 2
Prelude Data.Ratio> :t x
x :: Integral a => Ratio a
Data.Ratio
使用%
作为构造函数,但除非在Integral
类型类之前定义了该类型,否则它不能解释为什么%
可供Data.Ratio
使用。 (当然,合格的导入允许你在多个模块中使用相同的运算符名称,所以无论哪种方式,%
使用的Data.Ratio
都不是真正的原因。)
但请注意,Integral
定义了both mod
and rem
functions。我怀疑%
故意被排除在Integral
之外,以避免1)选择是否应该是mod
或rem
的别名,以及2)让人们记住做出了哪个选择。
此外,languages use different definitions for %
,所以(%) = mod
或(%) = rem
有可能混淆某人。