我决定自学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)
Run Code Online (Sandbox Code Playgroud)
当我尝试使用runHaskell tutorial03.hs运行该文件时,我收到此错误消息
tutorial03.hs:9:13:
Illegal signature in pattern: [Person] people
Use -XScopedTypeVariables to permit it
Run Code Online (Sandbox Code Playgroud)
使用XScopedTypeVariables标志我得到
tutorial03.hs:10:17: Not in scope: type variable `people'
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下我做错了什么.
pig*_*ker 25
Luqui说缩进就是问题.编译器将您的定义视为一样
let people :: [Person] people = read people_text
Run Code Online (Sandbox Code Playgroud)
确实看起来你正在模式中编写一个类型签名(并使用people它们作为函数名称和模式变量,以启动 - 特殊但允许!).
至关重要的是,let是一个布局关键字,引入了一条线条,这些线条应该全部缩进到相同的水平位置.通过使用更多缩进的行跟踪签名,您指示您使用签名对该行进行约束,而不是为实际定义开始新行.如果您不喜欢这种繁琐的布局约定,则可以使用嘈杂的分号.
如果您希望将您的定义视为两行,则需要注意people垂直排列...
let people :: [Person]
people = read people_text
Run Code Online (Sandbox Code Playgroud)
或以分号显示明确结束的行.
let people :: [Person] ;
people = read people_text
Run Code Online (Sandbox Code Playgroud)
前者是可取的,虽然我希望大多数Haskellers只提供类型注释read people_text而不是定义的签名,如下所示:
let people = read people_text :: [Person]
Run Code Online (Sandbox Code Playgroud)
一旦修复了这个问题,你就需要应对列表长度为数字的事实,但putStr输出字符串.该print命令可能对此更有用.