簡體   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