%在Haskell中做什么?

时间:2019-02-19 00:44:28

标签: haskell modulo

我习惯用%来表示其他语言中的“模”。在Haskell中,我们必须使用mod x yx `mod` y。那么,这个符号在Haskell中是用来做什么的?

5 个答案:

答案 0 :(得分:12)

快速浏览Hoogle,您会发现%是定义为的中缀函数

(%) :: Integral a => a -> a -> Ratio a

,您可能会猜到它是Data.Ratio库的一部分,该库主要处理比率(即:分数)。代码是

x % y = reduce (x * signum y) (abs y)

因此给定两个积分(x,y),它返回不可约分数x / y

答案 1 :(得分:6)

在Haskell中,我们可以像普通函数一样定义带有各种符号(包括%)的二进制运算符,因此您可以将%定义为所需的任意运算符(在定义它的模块中)

最典型的情况是,Data.Ratio module提供了%作为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

请记住,您可以在以下搜索引擎中搜索此类运算符和函数:

实际上,我已经查看了Hoogle是如何定义%的。

%是定义为

的中缀函数
(%) :: Integral a => a -> a -> Ratio a

,从上面的类型定义中,您可以看到它是Data.Ratio库的一部分,该库主要处理比率(即:分数)。它的代码是

x % y = reduce (x * signum y) (abs y)

因此给定两个积分(x,y),它返回不可约分数x / y

答案 2 :(得分:2)

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

答案 3 :(得分:1)

Data.Ratio使用%作为构造函数,但是除非该类型在Integral类型类之前定义,否则它不能解释为什么%可用的Data.Ratio使用。 (当然,合格的导入允许您在多个模块中使用相同的运算符名称,因此,%使用Data.Ratio并不是真正的原因。)

但是请注意,Integral定义了both mod and rem functions。我怀疑%被故意排除在Integral之外,这都是为了避免1)选择是否应该作为modrem的别名作为2)让人们记住做出了哪个选择。

还有languages use different definitions for %,所以(%) = mod(%) = rem都有可能使某人困惑。

答案 4 :(得分:0)

在“老派”戴维斯使用 Haskell 的函数式编程系统简介中找到了这个。 (他不断将 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)

然后

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,[])

这只是一个看起来很疯狂的嵌套函数的简洁版本

popStack (addStack (push 2.2 (multStack (subtStack (push 4.3 (divStack (push 6.7 (push 7.1 (push 12.2 emptyStack)))))))))

它本身避免为每个堆栈操作创建和传递一个新堆栈。总之,YAMAMOTO Yuji 开头所说的适用于这里,而不是真正的任何Ratio 东西 AFAIK。