Simple code error in Haskell

3

I'm starting on WinHugs, programming on Haskell. I'm new to Functional Programming. Since yesterday I am looking to solve the error that has in the code below but without success so far. Here is the code:

eq2grau::(Int->Int->Int)->Int 
eq2grau (a1, b1, c1) =
    if(delt1 (a1, b1, c1) > 0 ){
        then (((-b1) + sqrt(delt1(a1 b1 c1))) / (2 * a1))
        then (((-b1) - sqrt(delt1(a1 b1 c1))) / (2 * a1))
        }else
            if((delt1 (a1 b1 c1) == 0 ))
                then ((-b1)/(2 * a1))
                    else a1


delt1::Int->Int->Int->Int
delt1 ah be ce = 
            if(be > 0)
                then ((be * be) - (4 * ah *ce))
                    else ((be * be) - (4 * ah *ce))

    
asked by anonymous 11.04.2015 / 16:33

1 answer

4

There are a lot of errors in your code but the good news is that most of them are just syntax errors, which are easy to solve:)

Type declaration syntax

The type declaration says that eq2grau gets a single argument (which is a crazy function) and returns a Int . The right version gets the three arguments separated.

eq2grau :: (Int->Int->Int)->Int       -- errado
eq2grau :: Int -> Int -> Int -> Int -- certo

You also do not need a comma in the statement of arguments. The version you wrote gets a single argument (which is a tuple) instead of 3 separate arguments.

-- errado
eq2grau (a1, b1, c1) = ...

-- certo
eq2grau a1 b1 c1 =  ...

Function call syntax

In Haskell the function call syntax is only on the basis of the same space, and does not need a comma. The parentheses are wrapped around the whole call or individual parameters instead of going around the parameter list.

-- Nesses casos passamos 2 argumentos para f:
f x y
(f x y)
f x (y+z)

-- Já nesses outros casos, f só recebe 1 argumento
f(x,y)  -- f recebe uma tupla como argumento
f(x y)  -- x é uma função e f recebe o valor x aplicado em y.

In your case ...

delt1 (a1, b1, c1) > 0  -- errado
delt1 (a1  b1  c1) > 0  -- errado 

(delt a1 b1 c2)    > 0  -- certo
delt a1 b1 c1      > 0  -- também certo

Keys in if

Haskell does not use keys {} as in C

if( ... ){                -- errado
if ... then ... else ...  -- certo

In Haskell the normal thing is to group things via indentation, which neither in Python (be careful not to mix tabs with spaces, btw)

if x > y then
    "Hello world"
else
    "Goodbye world"

Note that you do not need parentheses around the conditional. You also do not need to% by% of each branch. The return of Haskell is already an expression with a value, similar to the ternary operator of C, if .

Multi-value return

Mean weird this ?: with 2 if né?

-- errado
then (((-b1) + sqrt(delt1(a1 b1 c1))) / (2 * a1))
then (((-b1) - sqrt(delt1(a1 b1 c1))) / (2 * a1))

I do not know how you hoped it would work :) The normal in Haskell (or any other language, to tell you the truth) would be to return a list of answers.

-- Precisa mudar o tipo da sua função pra dizer que retorna uma lista...
eq2grau::(Int->Int->Int)-> [Int]

-- .. e mudar os ifs.
if delt1 (a1, b1, c1) > 0 then
    -- Determinante positivo, duas soluções:
    [ ((-b1) + sqrt(delt1 a1 b1 c1)) / (2 * a1),
      ((-b1) - sqrt(delt1 a1 b1 c1)) / (2 * a1) ]
else if delt1 (a1, b1, c1) == 0
    -- Determinante zero, uma solução só:
    [ ((-b1)/(2 * a1)) ]
else
    -- Determinante negativo, nenhuma solução:
    [ ]

% redundant%

The indentation of this then is weird.

delt1 :: Int->Int->Int->Int
delt1 ah be ce = 
    if  be > 0
      then ((be * be) - (4 * ah *ce))
            else ((be * be) - (4 * ah *ce))

The normal would be

delt1 ah be ce = 
    if be > 0 then
        ((be * be) - (4 * ah *ce))
    else
        ((be * be) - (4 * ah *ce))

In addition, the two branches of if are the same. Did not even need the if!

delt1 ah be ce = 
   (be * be) - (4 * ah *ce)

Second degree equation with integers?

It will give a type error when you try to get the square root of an integer. Why not use floating-point numbers for everything?

eq2grau :: Double -> Double > Double -> [Double]
delt1 :: Double -> Double -> Double -> Double

Determinant account appears more than once

This is more a style suggestion, but why not use a if to avoid calculating the determinandte more than once? Programming in the ctrl-c-ctrl-v base is undesirable in any programming language:)

let d = delt1 a1 b1 c1 in

Summarizing everything

The version with all the fixes looks like this. I tested it and it worked.

eq2grau :: Double -> Double -> Double -> [Double]
eq2grau a1 b1 c1 =
  let d = delt1 a1 b1 c1
  if d > 0 then
    [ ((-b1) + sqrt d) / (2 * a1),
      ((-b1) - sqrt d) / (2 * a1)]
  else if d == 0 then
    [ (-b1)/(2 * a1) ]
  else
    []

delt1 :: Double -> Double -> Double -> Double
delt1 ah be ce =
  (be * be) - (4 * ah *ce)
    
11.04.2015 / 21:25