Pattern matching and write syntax function to retrieve a data type field

Given an example data type with write syntax:

data VmInfo = VmInfo {infoVid :: String ,infoIndex :: Int ,infoPid :: Int ,infoExe :: String } deriving (Show) 

and (vmInfo :: String → VmInfo), which generates and returns the above data structure, given the name vm as a string.

I can see two methods for extracting individual parts of the VmInfo data type.

 (VmInfo vid _ _ _) <- vmInfo vm 

This is just a pattern match. AND...

 vid <- infoVid <$> vmInfo vm 

using syntax generated syntax entries.

The question is simple: what is the preferred method?

The number of fonts is wise, they are the same, so I'm looking for speed, correctness / best practice.

I assume pattern matching will be faster, but then what is the point of the syntax of the record?

Thanks.

+6
source share
1 answer

They are not semantically equivalent.

Let's look at the first example:

 (VmInfo vid _ _ _) <- vmInfo vm 

Performs pattern matching in the binding operation. These are two results. First, the constructor of the result of the vmInfo vm action is vmInfo vm . This means that if vmInfo ended with a string of type return undefined , an exception caused by evaluating undefined will occur when this pattern matches, and not in the future use of vid . Secondly, if a pattern match is refuted (the pattern match does not match the value), the monad fail instance is called with the pattern matching error text. This is not possible in this case, but it is generally possible when the template matches the constructor in bind.

Now, to the following example:

 vid <- infoVid <$> vmInfo vm 

By definition, <$> , this will be completely lazy in the value returned by the action (and not the effects). If vmInfo ended with return undefined , you would not get an exception from the undefined evaluation until you did what used the vid value. In addition, if infoVoid was able to throw any exceptions, they would not end before using vid , the best case.

Interestingly, these differences are present only within the framework of monadic binding. If vmInfo was clean and you linked the vid name inside a let or where expression, they would generate identical code.

In this case, the one you want to use is completely up to you. Both are idiomatic Haskell. People usually choose what looks best in the context in which they work.

The main reasons people use access functions is brevity, when so many fields in a record have a huge coincidence of patterns, and because they are actual functions, they can be passed to any higher order function into which their type fits. You cannot pass pattern matches as a separate construct.

+8
source

Source: https://habr.com/ru/post/914000/


All Articles