0

Consider the following code:

import Data.Char

numToReal::Integral a => [a] -> [Double]
numToReal l = map (\x -> fromIntegral x) l

ordList::[Char] -> [Int]
ordList l = map ord l

squareList::Num a => [a] -> [a]
squareList l = map (\x -> x * x) l

main::IO()
main = do
    print(squareList [1..10])
    print(numToReal [1..10])
    print(ordList ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'])

Written as it is, the GHC complains the following error:

• Couldn't match expected type ‘(a2 -> IO ()) -> [Int] -> IO ()’
              with actual type ‘IO ()’
• The function ‘print’ is applied to three arguments,
  but its type ‘[Double] -> IO ()’ has only one
  In a stmt of a 'do' block:
    print
      (numToReal [1 .. 10]) print (ordList ['a', 'b', 'c', 'd', ....])
  In the expression:
    do print (squareList [1 .. 10])
       print (numToReal [1 .. 10]) print (ordList ['a', 'b', ....])

But if I do this:

import Data.Char

numToReal::Integral a => [a] -> [Double]
numToReal l = map (\x -> fromIntegral x) l

ordList::[Char] -> [Int]
ordList l = map ord l

squareList::Num a => [a] -> [a]
squareList l = map (\x -> x * x) l

main::IO()
main = do
    print(squareList [1..10])
    print(numToReal [1..10]);
    print(ordList ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']);

It compiles and runs just fine, aside from complaining that I'm using tabs instead of spaces. The question is, why the semicolon solves this error? Is there something to do how the compiler is parsing the file on those 2 last lines?

  • 5
    Looks like you did not use the same tabs/spaces/... for the last line. – Willem Van Onsem Aug 10 '22 at 17:31
  • You *can* use semicolons to separate the lines of a `do` block yes. – Willem Van Onsem Aug 10 '22 at 17:32
  • Listen to the compiler when it complains you're using tabs, and don't use them. They don't mean the same thing to the compiler as they do to your text editor. – Carl Aug 10 '22 at 17:37
  • @WillemVanOnsem oh my god, you where right. I deleted and put the tabs back on the three lines of the main function, the error vanished and it works perfectly, thanks! – Otávio Augusto Silva Aug 10 '22 at 17:41
  • 1
    @OtávioAugustoSilva: I would really advise *not* to use tabs but spaces. The "length" of a tab is not something that is standardized. Something can *look* nice in an editor, but the compiler might for example see a tab as just four spaces, and thus then it might look ugly. – Willem Van Onsem Aug 10 '22 at 17:47
  • 1
    @WillemVanOnsem Alternate solution: [use tabs in a way that gets interpreted the same no matter where tabstops occur](http://dmwit.com/tabs/). ;-) – Daniel Wagner Aug 10 '22 at 22:14
  • This is why I wish haskell was better at catching parsing problems. – Abastro Aug 12 '22 at 00:00

1 Answers1

2

In Haskell, tabstops happen every 8 columns. Your first two lines in the do block use four spaces, but the last uses one tab, so they don't line up in the compiler's eyes.

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380