[英]What does % do in Haskell?
我習慣於使用 % 來表示其他語言中的“模”。 在 Haskell 中,我們必須使用mod xy
或x `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
定義了mod
和rem
函數。 我懷疑%
被故意排除在Integral
,以避免 1) 選擇它是否應該是mod
或rem
的別名,以及 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.