我习惯用%来表示其他语言中的“模”。在Haskell中,我们必须使用mod x y
或x `mod` y
。那么,这个符号在Haskell中是用来做什么的?
答案 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)选择是否应该作为mod
或rem
的别名作为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。