Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write this case expression with the view pattern syntax?

After I have read the example of a RPN calculator in "Learn You a Haskell for Great Good!" I wanted to rewrite it myself in a more general way.

In order to easily extend the available functions I put these in separated lists and pattern matched with the lookup function using the ViewPatterns syntax. To read the input with read I wrote this:

parse xs x = case readMaybe x of
  Just x  -> Right (x : xs)
  Nothing -> Left "Syntax error

but I'd rather avoid a case expression and use again the view pattern like this:

parse xs (readMaybe -> Just x ) = Right (x : xs)
parse xs (readMaybe -> Nothing) = Left "Syntax error"

However with the latter I'm getting this error: No instance for (Read a0) arising from a use of ‘readMaybe’

I don't understand why. Aren't they equivalent?

The whole code is here.

like image 234
Rnhmjoj Avatar asked Feb 26 '15 21:02

Rnhmjoj


People also ask

What is the syntax of the case expression in SQL?

The syntax of the SQL CASE expression is: CASE [expression] WHEN condition_1 THEN result_1 WHEN condition_2 THEN result_2 ... WHEN condition_n THEN result_n ELSE result END case_name The CASE statement can be written in a few ways, so let’s take a look at these parameters. The parameters or components of the CASE SQL statement are:

How do you use an expression in a case statement?

The expressions are used within each condition without mentioning it at the start of the CASE statement. For example: CASE WHEN name = 'John' THEN 'Name is John' WHEN name = 'Steve' THEN 'Name is Steve' END

What is the return type of the case expression?

The CASE expression returns a result whose data type depends on the context where it is used. For example, if the CASE expression is used in the character string context, it returns the result as a character string. If the CASE expression is used in a numeric context, it returns the result as an integer, a decimal, or a real value.

How do you write a case statement in SQL?

There are actually two ways to use an SQL CASE statement, which are referred to as a “simple case expression” or a “searched case expression”. The expression is stated at the beginning, and the possible results are checked in the condition parameters.


1 Answers

They're not equivalent. The case version has one readMaybe, the view pattern version has two. For every readMaybe, the compiler has to infer which type is the target of the attempt to read. When the code says

parse xs x = case readMaybe x of
  Just x  -> Right (x : xs)
  Nothing -> Left "Syntax error

the GHC detective notices that in your Just x case, x ends up consed to xs, and so must take whatever type the elements of xs have. And that's good work.

But when you write

parse xs (readMaybe -> Just x ) = Right (x : xs)
parse xs (readMaybe -> Nothing) = Left "Syntax error"

you create two separate find-the-target-type problems, one for each use of readMaybe. The first of these is solved in just the same way as in the case case, but for the second, read individually,

parse xs (readMaybe -> Nothing) = Left "Syntax error"

there is just no clue what it is that you are failing to read, and no reason to believe it is the same thing as in the line above.

Generally, it is inappropriate to use view patterns unless there is only one outcome of interest. They are the wrong syntax if you want to do an intermediate computation once, but analyse the result into more than one case. I am happy to remain on the record that I consider them a misfeature for this reason.

like image 81
pigworker Avatar answered Sep 28 '22 00:09

pigworker