在對應用型實例的源代碼,也許我們有:哈斯克爾通配符使用
instance Applicative Maybe where
pure = Just
Just f <*> m = fmap f m
Nothing <*> _m = Nothing
Just _m1 *> m2 = m2
Nothing *> _m2 = Nothing
我原以爲「_」用作模式通配符。這裏'_m'和'_m2'的含義是什麼?這是GHC編碼慣例嗎?沒有使用_有一些性能優勢嗎?
在對應用型實例的源代碼,也許我們有:哈斯克爾通配符使用
instance Applicative Maybe where
pure = Just
Just f <*> m = fmap f m
Nothing <*> _m = Nothing
Just _m1 *> m2 = m2
Nothing *> _m2 = Nothing
我原以爲「_」用作模式通配符。這裏'_m'和'_m2'的含義是什麼?這是GHC編碼慣例嗎?沒有使用_有一些性能優勢嗎?
你說得對,_
是一個通配符。你在這裏看到的只是名稱以_
開頭的變量;沒有特別的語法。 _
和變量都匹配任何值,但_
表示您忽略該值。因此,如果您定義了一個變量並且不使用它,GHC會警告您,這很方便。但是,如果你想記錄什麼你忽略,而沒有被警告你忽略它?那麼,_
只是Haskell中的另一個單詞字符,所以你可以用它開始一個變量名。 GHC將假定您定義的任何_
-初始變量名稱是意圖未被使用,並且避免警告您有關它們。
因此,在
Just f <*> m = fmap f m
Nothing <*> _m = Nothing
的_m
用於明確的是,這是同樣的事情上面m
,但不被使用。如果我們用_
代替它,那可能不太清楚。如果我們用m
取代它,我們會得到一個警告:
…: warning: [-Wunused-matches]
Defined but not used: ‘m’
一般來說,_
只是有點特殊哈斯克爾模式匹配。除了上面的「無警告」屬性(它不會改變程序的功能,只有編譯器的消息),匹配_
幾乎完全像是與任何其他變量相匹配。只有兩點區別:
您可以一次匹配多個_
s。
star1, star2 :: a -> b -> Char
star1 _ _ = '*'
star2 x y = '*'
-- ILLEGAL:
-- star3 x x = '*'
每_
是截然不同的 - 兩個下劃線是不一樣的東西對方。但是,當我們與變量匹配時,我們所匹配的所有變量必須是不同的;你不能與「x」匹配兩次。 (您可以將_
視爲每次變量名稱不同的變量)。
不能在表達式中使用_
,只能在模式中使用。
id2 :: a -> a
-- ILLEGAL:
-- id1 _ = _
id2 x = x
因爲_
不會「記住」它匹配的反對,正如我們上面所看到的,你永遠不能在表達式中使用它。這只是一種模式。
如果不使用_
前綴,則編譯時得到警告:
gcc -Wall test.hs:
test.hs:21:18: Warning: Defined but not used: ‘m’
test.hs:23:11: Warning: Defined but not used: ‘m1’
test.hs:24:18: Warning: Defined but not used: ‘m2’
您可以使用_
避免警告。因此,_var
用於給變量命名並避免警告。你可以做這樣的事情:
Justa m1 *> _m = _m
但隨着通配符,你不能做這樣的事情:
Just m1 *> _ = _
但是下劃線變量沒有在RHS上使用? – andro
@andro在你的具體例子中,沒關係。使用'_'等同於'_var'。但總的來說,它們有所不同。 – Sibi