24、定义类型
1)Haskell使用Data语句定义数据类型
定义一个3维向量数据类型
data Vector3=Vector Float Float Float deriving(Show)
verctorlen::Vector3->Float
verctorlen (Vector x y z)=sqrt (x^2+y^2+z^2)
并定义长度函数verctorlen
*Main> verctorlen (Vector 12 10.2 8.2)
17.756126
我们还可以定义一个类似于记录的数据类型
data Student=Student String Int deriving (Show)
*Main> Student "lijun" 26
Student "lijun" 26
*Main>
完善一下这个记录数据类型
data Students=Students {
name::String
,age::Int
}deriving (Show)
*Main> Students {name="liming",age=26}
Students {name = "liming", age = 26}
*Main>
2)类型别名
Haskell可以使用type语句定义类型别名,我们把前面定义的向量的数据类型完善一下
type Vx=Float
type Vy=Float
type Vz=Float
data Vector3=Vector Vx Vy Vz deriving(Show)
然后加载程序,执行
*Main> Vector 12 18 17
Vector 12.0 18.0 17.0
*Main> verdctorlen(Vector 12 18 17)
27.513634
*Main>
再定义一个增加年纪的函数addage。
type Sname=String
type Sage=Int
type Student=(Sname,Sage)
addage::Student->Student
addage (sname,sage)=(sname,sage+1)
3)类型类
Haskell使用class定义类型类,然后使用instance语句定义类型类的实例
刚才我们定义一个学生的类型别名,这个学生的类型由Sname和Sage这2个类型组成,下面我们定义一个类型类及其实例,类型类对应3个函数,完成对2个学生年纪的比较。
程序如下:
type Sname=String
type Sage=Int
type Mystudent=(Sname,Sage)
data Student=Student Mystudent
class Mstage a where
agegt::a->a->Bool
ageeq::a->a->Bool
agelt::a->a->Bool
instance Mstage Student where
Student (sname1,sage1) `ageeq` Student (sname2,sage2)=if (sage1==sage2) then True else False
Student (sname1,sage1) `agegt` Student (sname2,sage2)=if (sage1>sage2) then True else False
Student (sname1,sage1) `agelt` Student (sname2,sage2)=if (sage1<sage2) then True else False
加载程序后运行:
*Main> Student ("lixing",22) `agegt` Student ("wangwu",23)
False
*Main> Student ("lixing",22) `agelt` Student ("wangwu",23)
True
*Main> Student ("lixing",22) `ageeq` Student ("wangwu",23)
False
*Main>
27、可运行程序与输入输出
(1)编译并运行程序
程序的函数名为main。
main=putStrLn ("hello");
然后编译:
ghc --make testmain
最后运行:
Testmain
hello
复杂的 I/O acttions 需要 do 语句块,以分号间隔
编写一个更复杂的例子,读入年龄,然后显示出来:
main=do
putStrLn ("hello,how old are you?");
age<-getLine;
putStrLn ("your age is:"++age)
然后编译后运行
H:\my_docs>ghc --make testmain
[1 of 1] Compiling Main ( testmain.hs, testmain.o )
Linking testmain.exe ...
H:\my_docs>testmain
hello,how old are you?
28
your age is:28
也可以使用下面方式运行:
runhaskell testmain.hs
(2)读写文件
程序为:
import System.IO
main=do
handle<-openFile "mytest2.hs" ReadMode;
contents<-hGetContents handle;
putStr contents;
hClose handle
运行后,将testmain.hs的内容显示出来。
H:\my_docs>runhaskell testmain.hs
type Vx=Float
type Vy=Float
type Vz=Float
data Vector3=Vector Vx Vy Vz deriving(Show)
verdctorlen::Vector3->Float
verdctorlen (Vector x y z)=sqrt (x^2+y^2+z^2)
.......................
也可以使用withFile函数
import System.IO
main=do
withFile "mytest2.hs" ReadMode (\handle->do
contents<-hGetContents handle;
putStr contents)
withFile接受以下几个参数:
文件名
IOMode(ReadMode|WriteMode|AppendMode|ReadWriteMode)
(Handle->IO a)这个参数实际是一个函数,目的是对文件本身进行操作。
readFile函数
import System.IO
main=do
contents<-readFile "mytest2.hs"
putStr contents
writeFile函数实现写文件
import System.IO
main=do
contents<-readFile "mytest2.hs"
writeFile "mytest2.txt" (map toLower contents)
appendFile向文件尾增加内容
import System.IO
main=do
contents<-getLine
writeFile "myinput.txt" (contents++"\n")
removeFile和renameFile实现删除文件和改文件名。
28、命令行参数
使用getArgs得到调用参数,使用getProgName得到程序名
29、随机数
Prelude System.Random> random (mkStdGen 200)::(Int,StdGen)
Loading package bytestring-0.9.2.1 ... linking ... done.
Loading package Win32-2.2.2.0 ... linking ... done.
Loading package array-0.4.0.0 ... linking ... done.
Loading package deepseq-1.3.0.0 ... linking ... done.
Loading package old-locale-1.0.0.4 ... linking ... done.
Loading package time-1.4 ... linking ... done.
Loading package random-1.0.1.1 ... linking ... done.
(1645576248,1850108509 1655838864)
Prelude System.Random>