基本语法
记录是和代数 data
类型的扩展,允许字段命名:
data StandardType = StandardType String Int Bool --standard way to create a sum type
data RecordType = RecordType { -- the same sum type with record syntax
aString::String
, aNumber::Int
, isTrue :: Bool
}
然后可以使用字段名称从记录中获取指定的字段
> let r = RecordType {aString = "Foobar", aNumber= 42, isTrue = True}
> :t r
r::RecordType
> :t aString
aString::RecordType -> String
> aString r
"Foobar"
记录可以与模式匹配
case r of
RecordType{aNumber = x, aString=str} -> ... -- x = 42, str = "Foobar"
请注意,并非所有字段都需要命名
记录是通过命名它们的字段来创建的,但也可以创建为普通的总和类型(当字段数很小且不太可能改变时通常很有用)
r = RecordType {aString = "Foobar", aNumber= 42, isTrue = True}
r' = RecordType "Foobar" 42 True
如果创建的记录没有命名字段,编译器将发出警告,结果值将为 undefined
。
> let r = RecordType {aString = "Foobar", aNumber= 42}
<interactive>:1:9: Warning:
Fields of RecordType not initialized: isTrue
> isTrue r
Error 'undefined'
可以通过设置其值来更新记录的字段。未提及的字段不会更改。
> let r = RecordType {aString = "Foobar", aNumber= 42, isTrue = True}
> let r' = r{aNumber=117}
-- r'{aString = "Foobar", aNumber= 117, isTrue = True}
为复杂的记录类型创建镜头通常很有用。