[英]Is it possible to pattern match by function in Haskell?
例如,我在 haskell 中有一個 function:
foo:: Int a => (a -> a -> b) -> a -> b
我想通過第一個參數進行模式匹配:
foo (+) a = a + a
foo (-) a = a - a
但是,此代碼會導致編譯器錯誤。 我嘗試使用警衛,但它也沒有幫助。 是否有可能實現這樣的模式匹配?
是否可以通過 Haskell 中的 function 進行模式匹配?
沒有。 賴斯定理[wiki]的結果之一是,一般無法確定兩個函數是否等價。 因此,這意味着可以構造一個可以將兩個數字相加的 function,但編譯器無法證明 function 等價於(+)
。
如果我們使用引用相等,那么\xy -> x + y
不應該與模式匹配,而直接傳遞(+)
會匹配。 這將是相當離奇的。 想象一下,您有一個 function f 0 = abs
或f 0 x = abs x
。 奇怪的是,function 的(小)實現細節可以確定另一個 function 的行為。
function 的定義是正確的(在 GHC 9.0.1 和 8.6.5 上測試過)。 但是,它不會檢查 function 是否為(+)
:您定義了一個名為(+)
的變量,您可以在 function 的主體中使用該變量。 您可以將其用作中綴運算符,例如x + y
或(+) xy
。 但 function 定義等同於:
foo :: (a -> a -> b) -> a -> a -> b
foo g x y = g x y
或者
foo :: (a -> a -> b) -> a -> a -> b
foo g x y = g x y
如果你打開-Wname-shadowing
警告,它會拋出一個警告,你有一個臨時變量與上面上下文中的變量沖突:
ghci> f (+) x y = x + y
<interactive>:1:3: warning: [-Wname-shadowing]
This binding for ‘+’ shadows the existing binding
imported from ‘Prelude’ (and originally defined in ‘GHC.Num’)
您的 function 的簽名可能會導致很多錯誤,這里的簽名應該是:
f :: (a -> b -> c) -> a -> b -> c
f (+) x y = x + y
但同樣,這與前奏中定義的(+)
function不匹配。
如果您需要一些參數來確定 function,您可以 - 正如@RobinZigmond 所說- 創建一個表示某些功能的類型,例如:
data FunctionSelector = Add | Sub deriving
foo :: Num a => FunctionSelector -> a -> a -> a
foo Add = (+)
foo Sub = (-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.