How to use guards with let in Haskell

1

I wanted to do this same problem that calculates the roots of a second degree function, but using let.

raizes2 :: Float -> Float -> Float -> (Float, Float)
raizes2 a b c 
  |delta < 0 = error "Delta nao pode ser menor que zero"
  |a == 0 = error "A nao pode ser zero"
  |otherwise = ((-b + (sqrt(delta)))/2*a, (-b - (sqrt(delta)))/2*a)
where
delta = (b^2 - 4*a*c)
    
asked by anonymous 26.09.2018 / 20:21

2 answers

2

You have to use case expressions. For example:

raizes2 :: Float -> Float -> Float -> (Float, Float)
raizes2 a b c = let delta = (b^2 - 4*a*c)
                in case compare delta 0 of
                     LT -> error "Delta nao pode ser menor que zero"
                     _  -> if a == 0
                           then error "A nao pode ser zero"
                           else ( (-b + (sqrt(delta)))/2*a
                                , (-b - (sqrt(delta)))/2*a )

It's a little different because case only compares equalities. And what is compared is static, that is, it will always be the result of compare delta 0 , which can be LT , GT or EQ . Since its patterns involve the comparison not only of the delta value, it is necessary to use the _ (which accepts anything) case and within it to create a if (or other case ) to compare the value of a .

If you want to read a little about these structures, the page about case is translated into Wikibook in Portuguese .

    
27.09.2018 / 04:19
0

You can not use guards inside the let directly. The guards come before the definition of the expression to be evaluated, and the let ja is that expression. But a way to solve (inelegantly) the problem is to define an auxiliary function inside the let, and in that definition to use the guards

raizes2 a b c = let delta = (b^2 - 4*a*c)
                    auxiliar
                        |delta < 0 = error "Delta nao pode ser menor que zero"
                        |a == 0 = error "A nao pode ser zero"
                        |otherwise = ((-b + (sqrt(delta)))/2*a, (-b - (sqrt(delta)))/2*a)
                in auxiliar

As I said, it is inelegant ....

    
11.10.2018 / 16:49