How does the Haskell function Guardian manipulate other values instead of function parameters?

In http://lisperati.com/haskell/ht4.html The author shows the function of reading polygons from a simple SVG file I understand most of the code, but I wonder if I can rewrite the function

let readPoint :: String -> Point
      readPoint s | Just [x,y] <- matchRegex (mkRegex "([0-9.]+),([0-9.]+)") s = (read x,read y)

In a more understandable form I find the line a little confusing because the guard should operate on the parameters of the function (in this case, "readpoint"), but the guard here obviously operates on the results of matchregex

So anyone can explain the magic behind it?

Can this be rewritten into a more understandable form?

Solution

You can think of guard as the syntax sugar of if statement The expression in guard can be any valid Boolean expression, just as in if statement This means that you can use any value and function within the scope

For example, you can override the following:

foo x | abc = ...
      | def = ...
      | otherwise = ...

as

foo x = if abc then ... else if def then ... else ...

We can also write it down in more detail in case instead of the following:

foo x = case abc of
  True -> ...
  False -> case def of
    True -> ...
    False -> ...

After all, if you are just a case of grammar sugar! Writing everything according to the case makes it easier to see that different functions are just syntax sugar for the same thing

The second expression makes sense even if the condition refers to existing variables (ABC and DEF) instead of function parameter X Guarding is just the same job

Your example is a little complicated because it uses an extension called "pattern guards" This means that the guard is not just a boolean, it can also try to match a pattern If the pattern matches, the defense is successful (for example, the same as the real guard); Otherwise, the defender cannot match (like getting false)

We can imagine rewriting as follows:

readPoint s | Just [x,y] <- matchRegex (mkRegex "...") s = ...
            | otherwise = ...

as

readPoint s = case matchRegex (mkRegex "...") s of
                Just [x,y] -> ...
                _ -> ...

You can see the parallelism between this and the normal guard's case version Pattern guard simply extends any pattern to any pattern, not just Boolean values

Again, I'm sure you'll agree that it makes sense to allow any expression in a case statement - there's no reason to limit it to using function parameters The same is true of the guards, because they are just grammar candy

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>