I am looking at this example using getOpts, and one portion of it really baffles me: the syntax of field labels.
First, this seems simple enough, creating a data type and declaring the initial values:
data Options = Options { optVerbose :: Bool
, optInput :: IO String
, optOutput :: String -> IO ()
}
startOptions :: Options
startOptions = Options { optVerbose = False
, optInput = getContents
, optOutput = putStr
}
Then getOpt
is used to go through the options and determine the actual parameters for the running program using a foldl
command... and then this let expression frustrates me:
let Options { optVerbose = verbose
, optInput = input
, optOutput = output } = opts
The boolean and functions verbose
, input
, and output
are then used after this. In most of the programming languages I'm more familiar with, this step would be written something like so:
verbose = opts.optVerbose
input = opts.optInput
output = opts.optOutput
Is Haskell's behavior here documented someplace?
It's just normal pattern-matching — just like when you write let (x:xs) = someList
and it assigns the first element to x
and the rest of the list to xs
.
If you wanted, you could write:
let verbose = optVerbose opts
input = optInput opts
output = optOutput opts
Pattern-matching is everywhere in Haskell and the ML family, but not as common in other languages.
This is standard Haskell syntax for defining, setting, and getting values of/from data type defined using records. For instance, in the record
data R a = R {v :: a,
f :: a -> a}
a value of type R a can be created, given a value x :: a
and a function g :: a -> a
, by
r = R {v = x, f = g}
Values of fields can be accessed in the following way:
get_v :: R a -> a
get_v = v
get_f :: R a -> a -> a
get_f = f,
I.e., get_f = f
and get_v = v
. Values can be set in a similar manner, using curly brackets:
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}
I.e., set_v
and set_f
are identical to
record {field = value}
where field
is the automatically generated function Haskell provides for access to a record field, and value is the desired value. The values of fields in a data type defined using records can be accessed and set using these operations. The let
expression in your example is creating a value of type Options
and setting the values of its fields.
(I'm pretty sure I'm not wrong about this, but if I am...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With