haskell - 简单的 Haskell 程序导致 'Illegal signature in pattern' 错误

标签 haskell

我决定自学 Haskell,我一生中从未如此沮丧过。我正在阅读 http://lisperati.com/haskell/ 上的教程这是我能找到的最简单的一个。我要做的就是读取一个名为 people.txt 的文本文件。其中包含一个数字列表并打印列表的长度。此代码直接来自教程。

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)

当我尝试使用 运行文件时runHaskell 教程03.hs 我收到此错误消息
tutorial03.hs:9:13:
Illegal signature in pattern: [Person] people
    Use -XScopedTypeVariables to permit it

使用我得到的 XScopedTypeVariables 标志
tutorial03.hs:10:17: Not in scope: type variable `people'

有人可以解释我做错了什么。

最佳答案

Luqui 认为缩进是问题是对的。编译器将您的定义视为

let people :: [Person] people = read people_text

这确实看起来像是在模式中编写类型签名(并使用 people 作为函数名和模式变量来启动 - 特殊但允许!)。

至关重要的是,let是一个布局关键字,引入了一 block 应该缩进到相同水平位置的行。通过使用更多缩进的行跟随签名,您表明您正在使用签名继续行,而不是为实际定义开始新行。如果您不喜欢这种繁琐的布局约定,您可以使用嘈杂的分号。

如果您希望将定义视为两行,则需要小心排列 people垂直...
let people :: [Person]
    people = read people_text

或用分号明确结束行。
let people :: [Person] ;
        people = read people_text

前者会更可取,尽管我预计大多数 Haskeller 只会为 read people_text 提供类型注释。而不是定义的签名,如下所示:
let people = read people_text :: [Person]

一旦你解决了这个问题,你将需要处理列表的长度是一个数字,但 putStr 输出字符串的事实。 print命令可能对此更有用。

关于haskell - 简单的 Haskell 程序导致 'Illegal signature in pattern' 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6787334/

相关文章:

haskell - Haskell 中的 From 和 ToJSON - 嵌套数据

Haskell:为什么使用代理?

Haskell - [Int] -> 字符串

list - 将整数插入列表中的特定位置

haskell - 可变性 : directly or via ST Monad

haskell - 代理、类型级别符号和 JSON

带有 Integral 类型类的 Haskell 斐波那契列表

haskell - GADT - 应用和用处?

haskell - 会使用 seq 代替 pseq 吗?

json - Haskell Data.Decimal 作为 Aeson 类型