繁体   English   中英

% 在 Haskell 中做什么?

[英]What does % do in Haskell?

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

快速浏览一下Hoogle ,您可以看到%是一个定义为的中缀函数

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

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

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

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

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

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

在 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使用% Data.Ratio是真正的原因。)

但是请注意, Integral定义modrem函数 我怀疑%被故意排除在Integral ,以避免 1) 选择它是否应该是modrem的别名,以及 2) 让人们记住做出了哪个选择。

此外, 语言对%使用不同的定义,因此(%) = mod(%) = rem都有可能混淆某人

在“老派”戴维斯介绍使用 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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM