我正在使用getOpts查看this example,其中一部分让我感到困惑:字段标签的语法。
首先,这看起来很简单,创建数据类型并声明初始值:
data Options = Options { optVerbose :: Bool
, optInput :: IO String
, optOutput :: String -> IO ()
}
startOptions :: Options
startOptions = Options { optVerbose = False
, optInput = getContents
, optOutput = putStr
}
然后使用getOpt
来查看选项并使用foldl
命令确定正在运行的程序的实际参数...然后让表达式让我感到沮丧:
let Options { optVerbose = verbose
, optInput = input
, optOutput = output } = opts
然后在此之后使用布尔和函数verbose
,input
和output
。在我更熟悉的大多数编程语言中,这一步都是这样编写的:
verbose = opts.optVerbose
input = opts.optInput
output = opts.optOutput
Haskell的行为是否记录在某处?
答案 0 :(得分:10)
这是正常的pattern-matching - 就像你写let (x:xs) = someList
时一样,它将第一个元素分配给x
,将其余部分分配给xs
。
如果你愿意,你可以写:
let verbose = optVerbose opts
input = optInput opts
output = optOutput opts
模式匹配在Haskell和ML系列中无处不在,但在其他语言中并不常见。
答案 1 :(得分:5)
这是标准的Haskell语法,用于定义,设置和获取使用记录定义的数据类型的值。例如,在记录中
data R a = R {v :: a,
f :: a -> a}
可以创建类型为R a的值,给定值x :: a
和函数g :: a -> a
,
r = R {v = x, f = g}
可以通过以下方式访问字段值:
get_v :: R a -> a
get_v = v
get_f :: R a -> a -> a
get_f = f,
即,get_f = f
和get_v = v
。可以使用大括号以类似的方式设置值:
set_v :: R a -> a -> R a
set_v r a = r {v = a}
set_f :: R a -> (a -> a) -> R a
set_f r g = r {f = g}
即,set_v
和set_f
与
record {field = value}
其中field
是自动生成的函数,Haskell提供对记录字段的访问,value是所需的值。可以使用这些操作访问和设置使用记录定义的数据类型中的字段值。示例中的let
表达式是创建类型Options
的值并设置其字段的值。
(我很确定我对此没有错,但如果我......)
答案 2 :(得分:1)
基本上,名称只是从数据类型(记录)中获取数据的函数。记录只是一种具有一些语法糖的数据类型,可以自动生成可以将数据拉出的函数。我不确定它是如何实际实现的。
您可以在opts上应用optVerbose以获取optVerbose的值。
喜欢
optVerbose opts