2012-04-11 29 views
23

Nói rằng tôi có những điều sau kiểu dữ liệu tùy chỉnh và chức năng trong Haskell:thành viên truy cập của một kiểu dữ liệu tùy chỉnh trong Haskell

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

Nếu tôi muốn tạo một hàm print_age in tuổi của một người, như vậy: print_age (Person "John" "Smith" 21) , làm cách nào để viết print_age để truy cập thông số độ tuổi? Tôi là một người hướng đối tượng, vì vậy tôi ra khỏi yếu tố của tôi ở đây. Tôi về cơ bản tìm kiếm tương đương với Person.age.

Trả lời

37

Ứng dụng chức năng là tiền tố, do đó, age person sẽ tương ứng với số person.age() phổ biến trong ngôn ngữ OOP. Chức năng print_age có thể được định nghĩa pointfree bởi hàm hợp

print_age = print . age 

hoặc điểm đầy đủ

print_age person = print (age person) 
16

này được gọi là cú pháp kỷ lục, LYAH has a good section on it (ctrl-f "Bản ghi cú pháp").

Khi kiểu dữ liệu được xác định bằng bản ghi, Haskell tự động xác định hàm có cùng tên với bản ghi để hoạt động như người truy cập, vì vậy trong trường hợp này age là người truy cập cho trường tuổi (có loại Person -> Int) và tương tự cho first_namelast_name.

Đây là những hàm bình thường của Haskell và được gọi là age person hoặc first_name person.

+0

Trong Frege (Haskell cho JVM) bản ghi giới thiệu một vùng tên, vì vậy bạn sẽ viết '' 'Person.age person'''. Mặt khác, Frege cho phép viết '' 'person.age''', giống như trong OO. – 0dB

+1

Là một newbee hoàn chỉnh (!), Tôi đang tìm thấy sự lộn xộn không gian tên được tạo ra bởi các bản ghi là xấu xí và bực dọc. Cú pháp Frege là hấp dẫn và, iiuc, tránh được vấn đề này. – Alan

+0

Ah, tôi thấy tôi không đơn độc: https://ghc.haskell.org/trac/ghc/wiki/Records/NameSpacing – Alan

4

Ngoài chức năng age được đề cập trong các câu trả lời khác, đôi khi thuận tiện khi sử dụng đối sánh mẫu.

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

Có một phần mở rộng khá vô hại, cho phép bạn bỏ qua các bit đặt tên:

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

... và khác, xem với độ ngờ vực khác nhau của các thành viên cộng đồng khác nhau, cho phép bạn thậm chí bỏ qua việc nói trường nào bạn muốn đưa vào phạm vi:

{-# LANGUAGE RecordWildCards #-} 
print_age Person { .. } = {- first_name, last_name, and age are all defined -} 
Các vấn đề liên quan