Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do Haskell field labels work?

Tags:

haskell

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?

like image 905
Kevin Cantu Avatar asked Dec 02 '22 04:12

Kevin Cantu


2 Answers

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.

like image 178
Chuck Avatar answered Dec 27 '22 21:12

Chuck


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...)

like image 26
emi Avatar answered Dec 27 '22 20:12

emi