简体   繁体   English

冗余模式与幺半群匹配

[英]Redundant pattern match with monoids

The following function defines a pretty-concatenation of strings., ie one that does not accumulate white space: 以下函数定义了一个非常串联的字符串,即不会累积空格的字符串:

(><) :: String -> String -> String
x >< "" = x
"" >< y = y
x >< y  = x <> " " <> y

The following ought to be the generalisation to any IsString type. 以下应该是对任何IsString类型的推广。 Type a needs to be in the Monoid class in order to concatenate with mconcat (= <> from Semigroup ): 键入a需要是在Monoid类,以便与来连接mconcat (= <>Semigroup ):

(><) :: (Monoid a, IsString a) => a -> a -> a
x >< mempty = x
mempty >< y = y                          -- redundant pattern match!
x >< y  = x <> (fromString " ") <> y     -- redundant pattern match!

Now, strangely, GHC warns that the second and third lines are a redundant pattern match. 现在,奇怪的是,GHC警告第二行和第三行是冗余模式匹配。

This is odd. 这很奇怪。 It's not even clear to me how an a that is (Monoid a, IsString a) but not Eq a can be used here. 我甚至不清楚如何在这里使用a (Monoid a, IsString a)而不是Eq a

What does work, however, is this: 但是,这有什么用呢:

(<+>) :: (Monoid a, IsString a, Eq a) => a -> a -> a
x <+> "" = x
...

Can anyone shed some light on this? 任何人都可以对此有所了解吗?

mempty is just a variable name here. mempty在这里只是一个变量名。 You may as well have written 你也可以写

x >< y = x
x >< y = y
x >< y = ...

Haskell does not automatically do equality tests when you introduce a new pattern with the same name as an existing binding - it just shadows the existing binding. 当您引入与现有绑定同名的新模式时,Haskell不会自动执行相等性测试 - 它只会隐藏现有绑定。 If you want equality, you have to ask for it with == tests, eg in a guard clause. 如果你想要相等,你必须用== tests来询问它,例如在一个保护条款中。

x >< y
    | x == mempty = y
    | y == mempty = x
    | otherwise = x <> " " <> y

Your mistake is very common when you starts with pattern matching and bonded named function. 当您开始使用模式匹配和绑定命名函数时,您的错误很常见。 When you declare functions and its equations, all things declared at the left part of the equals written in lower case are name variables, for example: 当声明函数及其方程式时,在小写的左侧部分声明的所有内容都是名称变量,例如:

 f sum x y = x (sum * y)

those names are confusing, because you might think that sum is a function, and x and y are numbers, but instead x is a function and sum and y are numbers, and x could be any function of type Num a -> a -> a . 这些名称令人困惑,因为你可能认为sum是一个函数,x和y是数字,但是x是函数而sumy是数字, x可以是Num a -> a -> a类型的任何函数Num a -> a -> a You cannot give a concrete kind of function in the left side. 你不能在左侧给出具体的功能。

so : 所以:

(><) :: (Monoid a, IsString a) => a -> a -> a
x >< mempty = x
mempty >< y = y                          -- redundant pattern match!
x >< y  = x <> (fromString " ") <> y     -- redundant pattern match!

there, mempty is just a name for you variable and not the actual mempty function you are trying to call. 在那里, mempty只是你变量的名称而不是你试图调用的实际mempty函数。 You cannot pattern match over a functions of an interface. 您无法通过接口的功能进行模式匹配。 Just over variables and data types- 仅仅是变量和数据类型 -

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM