Haskell字段标签如何工作?

Kev*_*ntu 3 haskell

我正在使用getOpts 查看此示例,其中一部分让我感到困惑:字段标签的语法.

首先,这看起来很简单,创建数据类型并声明初始值:

data Options = Options  { optVerbose    :: Bool
                        , optInput      :: IO String
                        , optOutput     :: String -> IO ()
                        }

startOptions :: Options
startOptions =  Options { optVerbose    = False
                        , optInput      = getContents
                        , optOutput     = putStr
                        }
Run Code Online (Sandbox Code Playgroud)

然后getOpt用于浏览选项并使用foldl命令确定正在运行的程序的实际参数...然后这个让表达式让我感到沮丧:

let Options { optVerbose = verbose
            , optInput = input
            , optOutput = output   } = opts
Run Code Online (Sandbox Code Playgroud)

布尔和功能verbose,input以及output随后在此之后使用.在我更熟悉的大多数编程语言中,这一步将被写成如下:

verbose = opts.optVerbose
input   = opts.optInput
output  = opts.optOutput
Run Code Online (Sandbox Code Playgroud)

Haskell的行为是否记录在某个地方?

Chu*_*uck 10

这只是普通的模式匹配 - 就像你编写时一样let (x:xs) = someList,它将第一个元素分配给x列表的其余部分xs.

如果你愿意,你可以写:

let verbose = optVerbose opts
    input   = optInput opts
    output  = optOutput opts
Run Code Online (Sandbox Code Playgroud)

模式匹配在Haskell和ML系列中无处不在,但在其他语言中并不常见.


dan*_*tin 5

这是标准的Haskell语法,用于定义,设置和获取使用记录定义的数据类型的值.例如,在记录中

data R a = R {v :: a,
              f :: a -> a}
Run Code Online (Sandbox Code Playgroud)

给定值x :: a和函数g :: a -> a,可以创建类型为R a的值

r = R {v = x, f = g}
Run Code Online (Sandbox Code Playgroud)

可以通过以下方式访问字段的值:

get_v :: R a -> a
get_v = v

get_f :: R a -> a -> a
get_f = f,
Run Code Online (Sandbox Code Playgroud)

即,get_f = fget_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}
Run Code Online (Sandbox Code Playgroud)

即,set_vset_f它们完全相同

record {field = value}
Run Code Online (Sandbox Code Playgroud)

fieldHaskell自动生成的函数在哪里提供对记录字段的访问,value是所需的值.可以使用这些操作访问和设置使用记录定义的数据类型中的字段值.let示例中的表达式是创建类型Options的值并设置其字段的值.

(我很确定我对此没有错,但如果我......)