anonymous
anonymous

Reputation: 313

Recieved "Variable not in Scope" error in Haskell when making guard function

I have this following code which has a guard function and prints out certain prices for a child, adult, and a senior:

tickets::String -> Integer -> Float
tickets x y
    |x == "Child" = 7.5 * fromIntegral y
    |x == "Adult" = 12.5 * fromIntegral y
    |otherwise = 8.0 * fromIntegral y
    
    
main = do
print& tickets "Child" 5

However when I try to run it, I get this error:

main.hs:9:6: error:
Variable not in scope: (&) :: (a0 -> IO ()) -> Float -> t

The Float part was supposed to have the function print out the total price of 5 child tickets according to my main function, and I want to know how to avoid this error while learning Haskell. It would be appreciated if someone would help me find out how to fix this error!

Upvotes: 2

Views: 5314

Answers (1)

eric
eric

Reputation: 1059

Haskell can be challenging to learn at first. Thankfully, you have some good tools at your disposal (stack, ghci, etc).

First, note the error you're getting. It's saying that the variable (&) is not in scope. That should be your first hint something's up/awry.

main.hs:9:6: error:
Variable not in scope: (&) :: (a0 -> IO ()) -> Float -> t

The above error message means that the compiler doesn't understand some variable (&) because it's not "in scope." This means that, for whatever reason, the compiler can't "see" any definitions for this variable––either it isn't defined at all or the module it is defined in hasn't been imported.

The other thing you can do is inspect the types of the code you have now, compare these types to those the types you want to produce, and then fill in the gaps.

For example, you can start ghci with stack ghci in your project root. Then you can inspect the type of print:

> :t print
print :: Show a => a -> IO ()

This says print takes some type a that implements Show. If we then inspect tickets we see:

:t tickets
tickets :: String -> Integer -> Float

Then as a quick "sanity check" we could check that Float's are showable:

> show ((7.5)::Float)
"7.5"

Now we have a good idea about what main should look like:

main :: IO ()
main = print (tickets "Child" 5)

As other people have pointed out, $ can used here ($ can help reduce the number of parenthesis in your code):

main :: IO ()
main = print $ tickets "Child" 5

And there you have it! Hopefully this helps to demystify Haskell a bit :)

Upvotes: 5

Related Questions