简体   繁体   English

在 Haskell 中访问自定义数据类型的成员

[英]Accessing members of a custom data type in Haskell

Say I have the following custom data type and function in Haskell:假设我在 Haskell 中有以下自定义数据类型和函数:

data Person = Person { first_name :: String, 
                       last_name :: String,
                       age :: Int 
                     } deriving (Eq, Ord, Show)

If I want to create a function print_age to print a Person's age, like so: print_age (Person "John" "Smith" 21) , how would I write print_age to access the age parameter?如果我想创建一个函数print_age来打印一个人的年龄,像这样: print_age (Person "John" "Smith" 21) ,我将如何编写print_age来访问年龄参数? I'm an Object Oriented guy, so I'm out of my element here.我是一个面向对象的人,所以我不在这里。 I'm basically looking for the equivalent of Person.age.我基本上是在寻找相当于 Person.age 的东西。

Function application is prefix, so age person would correspond to the person.age() common in OOP languages.函数 application 是前缀,所以age person将对应于 OOP 语言中常见的person.age() The print_age function could be defined pointfree by function composition print_age函数可以通过函数组合来定义 pointfree

print_age = print . age

or point-full或点满

print_age person = print (age person)

This is called record syntax, LYAH has a good section on it .这称为记录语法, LYAH 有一个很好的部分

When a datatype is defined with records, Haskell automatically defines functions with the same name as the record to act as accessors, so in this case age is the accessor for the age field (it has type Person -> Int ), and similarly for first_name and last_name .当使用记录定义数据类型时,Haskell 会自动定义与记录同名的函数作为访问器,因此在这种情况下age是年龄字段的访问器(它的类型为Person -> Int ),对于first_name也类似和last_name

These are normal Haskell functions and so are called like age person or first_name person .这些是正常的 Haskell 函数,因此被称为age personfirst_name person

In addition to the age function mentioned in other answers, it is sometimes convenient to use pattern matching.除了其他答案中提到的age函数外,有时使用模式匹配也很方便。

print_age Person { age = a } = {- the a variable contains the person's age -}

There is a pretty innocuous extension that allows you to skip the naming bit:有一个非常无害的扩展,可以让你跳过命名位:

{-# LANGUAGE NamedFieldPuns #-}
print_age Person { age } = {- the age variable contains the person's age -}

...and another, viewed with varying degrees of distrust by various community members, which allows you to even skip saying which fields you want to bring into scope: ...还有另一个,被各种社区成员以不同程度的不信任看待,这使您甚至可以跳过说您想要将哪些领域纳入范围:

{-# LANGUAGE RecordWildCards #-}
print_age Person { .. } = {- first_name, last_name, and age are all defined -}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM