[英]What does % do in Haskell?
I'm used to using % to mean "modulo" in other languages.我习惯于使用 % 来表示其他语言中的“模”。 In Haskell, we have to use
mod xy
or x `mod` y
.在 Haskell 中,我们必须使用
mod xy
或x `mod` y
。 So, what is this symbol used for in Haskell?那么,这个符号在 Haskell 中是做什么用的呢?
With a quick look on Hoogle , you can see that %
is an infix function defined as快速浏览一下Hoogle ,您可以看到
%
是一个定义为的中缀函数
(%) :: Integral a => a -> a -> Ratio a
and as you can guess it is part of the Data.Ratio
library, which mostly deals with ratios (ie: fractions).你可以猜到它是
Data.Ratio
库的一部分,主要处理比率(即:分数)。 It is code is它的代码是
x % y = reduce (x * signum y) (abs y)
thus given two integrals (x,y) , it returns an irreducible fraction x/y因此给定两个积分 (x,y) ,它返回一个不可约分数 x/y
In Haskell, we can define binary operators with various symbols (including %
) like ordinary functions, So you can define %
as an arbitrary operator you want (in the module which you define it).在 Haskell 中,我们可以像普通函数一样定义带有各种符号(包括
%
)的二元运算符,因此您可以将%
定义为您想要的任意运算符(在您定义它的模块中)。
As the most typical case, %
is provided as the constructor of the Ratio
type by Data.Ratio module .作为最典型的情况,
%
被Data.Ratio 模块提供为Ratio
类型的构造函数。
Try the code below on GHCi to make sure that %
is provided by Data.Ratio
:在 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
And remember you can search such operators and functions in these search engines:请记住,您可以在这些搜索引擎中搜索此类运算符和函数:
Actually I've looked up how %
is defined by Hoogle .实际上,我已经查过 Hoogle是如何定义
%
。
% is an infix function defined as % 是一个中缀函数,定义为
(%) :: Integral a => a -> a -> Ratio a
and from the type definition above, you can see that it is part of the Data.Ratio
library, which mostly deals with ratios (ie: fractions).并且从上面的类型定义可以看出它是
Data.Ratio
库的一部分,主要处理比率(即:分数)。 Its code is它的代码是
x % y = reduce (x * signum y) (abs y)
thus given two integrals (x,y) , it returns an irreducible fraction x/y因此给定两个积分 (x,y) ,它返回一个不可约分数 x/y
Searching for (%)
on Stackage Hoogle , it appears that Data.Ratio
defines the %
operator as constructing a Ratio
value from a numerator and denominator.在 Stackage Hoogle 上搜索
(%)
,似乎Data.Ratio
将%
运算符定义为根据分子和分母构造Ratio
值。 A GHCi example:一个 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
uses %
as a constructor, but unless that type was defined before the Integral
type class, it doesn't explain why %
was available for use by Data.Ratio
. Data.Ratio
使用%
作为构造函数,但除非该类型是在Integral
类型类之前定义的,否则它无法解释为什么%
可供Data.Ratio
使用。 (Of course, qualified imports allow you to use the same operator name in multiple modules, so either way, %
being used by Data.Ratio
isn't really a reason.) (当然,限定导入允许您在多个模块中使用相同的运算符名称,因此无论哪种方式,
Data.Ratio
使用%
Data.Ratio
是真正的原因。)
Note, however, that Integral
defines both mod
and rem
functions .但是请注意,
Integral
定义了mod
和rem
函数。 I suspect that %
was intentionally left out of Integral
, both to avoid 1) making a choice as to whether it should be an alias for mod
or rem
, as well as 2) making people remember which choice was made.我怀疑
%
被故意排除在Integral
,以避免 1) 选择它是否应该是mod
或rem
的别名,以及 2) 让人们记住做出了哪个选择。
Also, languages use different definitions for %
, so either (%) = mod
or (%) = rem
had the potential for confusing someone .此外, 语言对
%
使用不同的定义,因此(%) = mod
或(%) = rem
都有可能混淆某人。
Found this in "Old School" Davies Introduction to Functional Programming Systems Using Haskell .在“老派”戴维斯介绍使用 Haskell 的函数式编程系统中找到了这个。 (He constantly compares Haskell to Pascal.) It's a simulation of stack arithmetic
(他经常将 Haskell 与 Pascal 进行比较。)这是堆栈算法的模拟
type Stack = [Float]
push :: Float -> Stack -> Stack
push x stack = x : stack
addStack :: Stack -> Stack
addStack (x:y:stack) = (y + x) : stack
subtStack :: Stack -> Stack
subtStack (x:y:stack) = (y - x) : stack
multStack :: Stack -> Stack
multStack (x:y:stack) = (y * x) : stack
divStack :: Stack -> Stack
divStack (x:y:stack) = (y / x) : stack
emptyStack :: Stack
emptyStack = []
popStack :: Stack -> (Float, Stack)
popStack (top:rest) = (top,rest)
Then然后
let f % g = g . f
actionsOn = push 12.2 %
push 7.1 %
push 6.7 %
divStack %
push 4.3 %
subtStack %
multStack %
push 2.2 %
addStack
in popStack (actionsOn emptyStack)
(-37.331642,[])
This is just a neater version of a crazy-looking nested function这只是一个看起来很疯狂的嵌套函数的更简洁版本
popStack (addStack (push 2.2 (multStack (subtStack (push 4.3 (divStack (push 6.7 (push 7.1 (push 12.2 emptyStack)))))))))
which itself avoids creating and passing a new stack for each stack operation.它本身避免为每个堆栈操作创建和传递一个新堆栈。 In summary, what YAMAMOTO Yuji says right at the beginning is applicable here and not really any
Ratio
stuff AFAIK.总之,YAMAMOTO Yuji 一开始所说的适用于这里,而不是真正的任何
Ratio
东西 AFAIK。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.