开发者

Simple Haskell program causes 'Illegal signature in pattern' error

I've decided t开发者_JAVA百科o teach myself Haskell and I have never been so frustrated in all my life. I am going through the tutorial at http://lisperati.com/haskell/ which is the easiest one I could find. All that I am trying to do is read a text file called people.txt which contains a list of numbers and print the length of the list. This code is straight from the tutorial.

import Data.List

type Person = [Int]

main = do

    people_text <- readFile "people.txt"
    let people :: [Person]
            people = read people_text

    putStr "Number of people "
    putStr (length people_text)

When I try to run the file with runHaskell tutorial03.hs I get this error message

tutorial03.hs:9:13:
Illegal signature in pattern: [Person] people
    Use -XScopedTypeVariables to permit it

Using the XScopedTypeVariables flag I get

tutorial03.hs:10:17: Not in scope: type variable `people'

Could someone please explain what I am doing wrong.


Luqui's right that indentation is the issue. The compiler is treating your definition as if it were

let people :: [Person] people = read people_text

which does indeed look like you're writing a type signature in a pattern (and using people both as the function name and a pattern variable, to boot -- peculiar but permitted!).

Crucially, let is a layout keyword, introducing a block of lines which should all be indented to the same horizontal position. By following the signature with a more-indented line, you indicate that you're contuing the line with the signature, rather than starting a new line for the actual definition. If you don't like this fussy layout convention, you can use noisy semicolons.

If you want your definition to be treated as two lines, you either need to be careful to line up the peoples vertically...

let people :: [Person]
    people = read people_text

or to signal the line ending explicitly with a semicolon.

let people :: [Person] ;
        people = read people_text

The former would be preferable, although I expect most Haskellers would just supply a type annotation for read people_text rather than a signature for the definition, like this:

let people = read people_text :: [Person]

Once you've fixed that, you'll need to contend with the fact that the length of the list is a number, but putStr outputs strings. The print command may be more useful for this purpose.


change it to this, works for me:

...
    let people :: [Person]
        people = read people_text

...
    print (length people_text)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜