46

假设我在 Haskell 中有以下自定义数据类型和函数:

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

如果我想创建一个函数print_age来打印一个人的年龄,像这样:print_age (Person "John" "Smith" 21),我将如何编写print_age来访问年龄参数?我是一个面向对象的人,所以我在这里没有我的元素。我基本上是在寻找 Person.age 的等价物。

4

3 回答 3

62

函数应用是前缀,所以age person会对应person.age()OOP语言中的通用。该print_age函数可以通过函数组合来定义

print_age = print . age

或点满

print_age person = print (age person)
于 2012-04-11T23:58:43.907 回答
23

这称为记录语法,LYAH 有一个很好的部分

当使用记录定义数据类型时,Haskell 会自动定义与记录同名的函数作为访问器,因此在这种情况下age是年龄字段的访问器(它具有 type ),对于andPerson -> Int也是类似的。first_namelast_name

这些是普通的 Haskell 函数,因此被称为 likeage personfirst_name person

于 2012-04-12T00:04:34.937 回答
12

除了age其他答案中提到的功能外,有时使用模式匹配也很方便。

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

有一个非常无害的扩展,允许您跳过命名位:

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

...还有另一个,不同社区成员以不同程度的不信任看待,这使您甚至可以跳过说出要纳入范围的字段:

{-# LANGUAGE RecordWildCards #-}
print_age Person { .. } = {- first_name, last_name, and age are all defined -}
于 2012-04-12T04:14:09.413 回答