在Maybe的Applicative实例的源代码中:
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编码惯例吗?不使用_?
是否有一些性能优势答案 0 :(得分:3)
你是对的_
是通配符。您在此处看到的只是名称以_
开头的变量;没有特殊的语法。 _
和变量都匹配任何值,但_
表示您忽略该值。因此,如果您定义变量并且不使用变量,GHC将警告您,这会派上用场。但是,如果您想记录您忽略的,而不是被警告您忽略它,该怎么办?好吧,_
只是Haskell中的另一个单词字符,所以你可以用它开始一个变量名。 GHC将假设您定义的任何_
- 初始变量名称意图未使用,并且不会向您发出警告。
因此,在
Just f <*> m = fmap f m
Nothing <*> _m = Nothing
_m
用于表明它与上面的m
相同,但未被使用。如果我们将其替换为_
,则可能不太清楚。如果我们将其替换为m
,我们会收到警告:
…: warning: [-Wunused-matches]
Defined but not used: ‘m’
通常,_
在Haskell模式匹配中只是有点特殊。除了上面的“无警告”属性(不改变程序所做的,只有编译器消息),与_
匹配几乎完全匹配任何其他变量。只有两个不同之处:
您可以同时匹配多个_
。
star1, star2 :: a -> b -> Char
star1 _ _ = '*'
star2 x y = '*'
-- ILLEGAL:
-- star3 x x = '*'
每个_
都是不同的 - 两个下划线不是彼此相同的。但是,当我们匹配变量时,我们匹配的所有变量必须是不同的;你不能两次匹配“x”。 (您可以将_
视为每次名称不同的变量。)
您不能在表达式中使用_
,只能在模式中使用。
id2 :: a -> a
-- ILLEGAL:
-- id1 _ = _
id2 x = x
因为_
没有“记住”它匹配的内容,正如我们上面所见,你永远不能在表达式中使用它。它只是一种模式。
答案 1 :(得分:1)
如果您不使用_
前缀,则在编译时会收到警告:
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 *> _ = _