2.
第一步
首先,你需要安装
GHC
。在
Linux
环境,它常常被预安装了或者能够通过
apt-get
或者
yum
命令获得。它也可以从
http://www.haskell.org/ghc/
下载。二进制包大概是最容易的,除非你真的知道你在做什么。
GHC
应该像其他的软件包一样下载和安装。这个教程在
Linux
下面完成,但是如果你知道如何使用
DOS
命令行所有的东西应该能够在
Windows
环境下工作。
有一个非常棒的
Emacs
mode
提供给
UNIX
(或者
Windows
Emacs)
用户,包括语法高亮和自动缩进。
Windows
用户能够使用记事本或者其他文本编辑器;
Haskell
语法对记事本相当友好,尽管你需要对缩进小心处理。
现在,是时候写你的第一个
Haskell
程序。这个程序将通过命令行读入一个名字然后输出一个问候。建立一个文件一
".hs”
结尾并输入下列代码:
module Main where
import System.Environment
main :: IO ()
main = do args <- getArgs
putStrLn ("Hello, " ++ args !! 0)
让我们看看这段代码。最开始的两行指定了我们将创造一个以
Main
命名的模块,这个模块将引入
(import)
System
模块。每一个
Haskell
程序从一个
Main
模块的
main
函数开始。那个模块可以导入其它模块,但是必须把它提供给编译器生成一个可执行文件。
Haskell
是区分大小写的:模块的名字永远是大写开头的,生命永远是非大写开头的。
main ::
IO ()
这一行是一个类型声明:
"main”
函数有
"IO
()”
类型。类型声明在
Haskell
里面是可选的:编译器能够自动的识别他们,当你的声明和编译器自动识别发生冲突的时候它会报错。在这个教程里,为了更清晰,所有的类型声明我都显式声明了。当你在家里跟随这个教程的时候,你可能想要忽略这些类型声明,因为在我们编写这个程序的时候不需要改动它们。
IO
类型是
monad
的一个实例,
monad
是一个吓人的名词不过含义却很简单。简单说,
monad
是一个声明“有一些附加信息,大多数函数都不要对这些附加信息担心”的方法。在这个例子里,“附加信息”是这个函数执行了
IO
的情况,而它的基本值是无,用
"()”
表示。
Monadic
值常被称作
"actions”
,因为这是最容易的方法来思考
IO
monad
是一系列的动作,而这些动作可能会影响外界世界。
Haskell
是一个声明式语言:除了告诉计算机一系列需要执行的指令,你还告诉它如何执行这些函数的定义。这些定义将各种动作和函数组合在一起。编译器识别出把所有定义放在一起的执行路径。(
bad
)
要写一个这样的定义,你需要建立一个等式。等式的左边定义一个名字,可能会有一个或者更多的会与变量帮定的
patterns
(后面解释
)
。等式的右边定义 (TODO)
<!--
@page { margin: 0.79in }
P { margin-bottom: 0.08in }
A:link { so-language: zxx }
-->
了一些其它告诉计算机当碰到这些名字应该干什么的定义。这些等式表现得就像一般的代数等式:你总是可以在程序里用右边的部分替代左式,这种替换不会改变计算值。这种行为被称作
"referential
transparency"
,这种性质使得
Haskell
代码比其它的语言容易懂得多。
那我们又要如何定义
main
函数呢?我们知道必须有一个
IO
()
动作,而且我们想要它读入命令行参数,然后答应一些输出。这里有两种方法创建一个
IO
动作:
-
用
return
函数提升
(lift)
一个普通值进入
IO
monad
。
-
把两个
IO
动作连接起来。
因为我们要做两件事情,我们将使用第二种方法。内建动作
getArgs
读入所有命令行参数并把它们存入一个字符串列表。内建函数
putStrLn
将一个字符串输出到终端。
我们使用
do-block
连接它们。
do-block
包括很多行,所有的行按照第一个非空白字符在
do
后面排列。每一行能有下面两种形式之一:
-
name <- action
-
action
第一种形式将
action
的结果和
name
绑定。例如,如果有一个动作的类型是
IO
[String](
一个
IO
动作会返回一个字符串列表,就像
getArgs)
,然后
"name”
就会和这个返回的字符串列表绑定。爹人中形式会执行这个动作,把上面的行用
>>
操作符连结在一起。这个操作符在不同的
monad
里面有不同的语义:如果在
IO
monad
中,他会连续执行所有的动作,执行无论什么会产生外部副作用的操作。因为这个连接符的语义依赖你使用的
monad
,所以你不能在同一个
do-block
里把不同
monad
类型的操作连在一起。
当然,这些动作可能自己就是函数的结果或者复杂的表达式。在这个例子里,我们首先取出参数列表中的
0
元素
(args
!! 0)
,把他连接到字符串
"Hello,
“
的后面
(“Hello,
“
++)
,最后把结果传给
putStrLn
。字符串在
Haskell
是一串字符,所以在字符串上你可以使用任何列表函数和操作符。一个标准操作符和它们的优先权如下表:
(table
omited)
编译和运行这个程序,你可以这么做:
debian:/home/jdtang/haskell_tutorial/code# ghc -o hello_you listing2.hs
debian:/home/jdtang/haskell_tutorial/code# ./hello_you Jonathan
Hello, Jonathan
-o
选项指定了你想创造的可执行程序的名字,然后你指定
Haskell
源程序名字。
习题:
1.修改程序,让它从命令行读入两个参数,然后输入一个包括这两个参数的信息。
2.修改程序,让它对输入的两个参数执行一个简单的算术操作然后把结果输出。你可以使用
read
来转换字符串成数字,和
show
转换一个数字回字符串。再用不同的操作符试试。
3.getLine
是一个
IO
动作,它能从终端读入一行然后把结果作为字符串返回。修改程序让它提示需要一个名字,然后读入名字,最后输出它。而不是从命令行读入。
分享到:
相关推荐
Write a Scheme interpreter in Haskell step by step.
《Teach Yourself Scheme in Fixnum Days》是一本关于Scheme编程语言的自学教程,本书内容涵盖了从基础到高级的多个知识点,致力于让读者在有限的天数内掌握Scheme编程。在进行知识点梳理之前,我们先对文档内容进行...
《Teach Yourself Scheme in Fixnum Days》是一本由Dorai Sitaram编写的经典书籍,旨在教授读者如何在有限的时间内掌握Scheme编程语言。Scheme是Lisp家族的一种方言,以其简洁性和灵活性而著称,是计算机科学教育和...
《Teach Yourself Scheme in Fixnum Days》是一本详尽的教程,旨在帮助读者在有限的时间内掌握Scheme语言的基础及进阶知识。此书由Dorai Sitaram撰写,并且在网络上部分中文翻译已经存在(参考链接:...
Chapters are organized as a series of groups, or "layers," each of which advances the reader to a new level in Scheme. The first layer (chapters 2-7) introduces Scheme procedures - how to define, use,...
编写自己的方案无编译器错误“为自己编写一个计划”教程,其中包含一些微不足道的修改。 涉及 Read 类型类的错误非常令人分心; 我已经在listing7.hs、listing8.hs 等中留下了关于重叠模式匹配的警告,因为它只是一...
scheme语言相关的学习资料: guide_racket_scheme.pdf Lisp之根源.pdf Racket图文教程.pdf scheme-primer.pdf ...The_Little_Schemer.pdf ...Write_Yourself_a_Scheme_in_48_Hours.pdf The+Seasoned+Schemer.pdf
标题 "write-yourself-a-scheme:48小时内为自己编写计划的游乐场" 指的是一项挑战,旨在引导参与者在48小时内学习并实现Scheme语言的一个简易解释器。这是一个编程项目,通过它,开发者可以深入理解编程语言的内部...
"A Preprocessing Scheme for High-Cardinality Categorical Attributes"这个主题探讨的就是如何有效地处理这类问题。 一、高基数类别变量的挑战 1. 维度灾难:高基数会导致数据的维度增加,这可能会引起过拟合,...
(How to Write a (Lisp) Interpreter (in Python))和(An ((Even Better) Lisp) Interpreter (in Python))的翻译,对解释器实现原理和函数式编程敢兴趣的可以下载看看!
### 一种非采样轮廓域中的新型彩色图像水印方案 #### 概述 本文介绍了一种基于非采样轮廓变换(NSCT)和支持向量回归(SVR)技术的新型彩色图像水印算法。该算法针对几何畸变攻击具有良好的抵抗能力,能够在保持...
This thoroughly updated edition of The Scheme Programming Language provides an introduction to Scheme and a definitive reference for standard Scheme, presented in a clear and concise manner....
scheme语言的解释器scheme48
标题 "scheme_in_forth.tar_in_scheme_forth_源码" 提供的信息表明,这是一个关于用Forth语言实现Scheme解释器的项目。Forth是一种结构简单、效率高的编程语言,而Scheme是Lisp家族的一种方言,以其简洁的语法和强大...
《A Tour of Scheme in Gambit》是一份详尽的指南,旨在介绍如何在Gambit-C解释器中使用Scheme语言进行编程。这份文档由Mikael More撰写,并且允许免费无限传播,前提是保留原有的版权信息。文档提供了PDF、HTML和...
针对802.11n的聚合机制,提出一种解决方法:In this paper, we proposed an A-MSDU frame aggregation with sub-frame integrity check and retransmission at the MSDU level without altering the original MAC ...
2. **兼容性测试**:不同的设备和操作系统版本可能对scheme的支持程度不同,需要进行充分的测试确保在各种环境下都能正常工作。 3. **用户体验**:当用户设备上没有注册对应的APP时,scheme链接通常会导致错误提示...