例如我在haskell中有一個函式:
foo :: Int a => (a -> a -> b) -> a -> b
我想通過第一個引數進行模式匹配:
foo ( ) a = a a
foo (-) a = a - a
但是,此代碼會導致編譯器錯誤。我嘗試使用警衛,但也無濟于事。是否有可能實作這樣的模式匹配?
uj5u.com熱心網友回復:
是否可以在 Haskell 中按功能進行模式匹配?
沒有。賴斯定理[wiki]的結果之一是,一般無法確定兩個函式是否等價。因此,這意味著可以構造一個可以將兩個數字相加的函式,但編譯器無法證明該函式等效于( )。
如果我們使用參考相等,那么\x y -> x y不應該與模式匹配,而( )直接傳遞會匹配。這會比較奇怪。假設您有一個函式f 0 = abs, 或f 0 x = abs x。一個函式的(小)實作細節可以決定另一個函式的行為,這將是很奇怪的。
函式定義是正確的(在 GHC 9.0.1 和 8.6.5 上測驗過)。但是,它不會檢查函式是否為( ):您定義了一個( )可以在函式體中使用的命名變數。您可以將其用作中綴運算子,例如x y, 或 as ( ) x y。但函式定義與:
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 = x `g` 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’)
你的函式簽名可能會導致那么多錯誤,這里的簽名應該是:
f :: (a -> b -> c) -> a -> b -> c
f ( ) x y = x y
但同樣,這與Prelude 中定義的函式不匹配( )。
如果你需要一些引數來確定一個函式,你可以 - 正如@RobinZigmond 所說- 創建一個代表某些函式的型別,例如:
data FunctionSelector = Add | Sub
foo :: Num a => FunctionSelector -> a -> a -> a
foo Add = ( )
foo Sub = (-)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/370612.html
