2012-02-28 31 views
7

Tôi mới là Haskell (và lập trình chức năng nói chung) và đã tự hỏi làm thế nào tôi có thể truy cập vào phần tử mới mà tôi đã thêm vào danh sách bằng toán tử cons (:)?Làm cách nào để truy cập phần tử danh sách mà tôi đã thêm với toán tử cons (:)?

Ví dụ, sử dụng WinGHCi tôi có thể tạo một danh sách mới và truy cập vào các yếu tố đầu tiên:

ghci> let a = [1,2,3] 
ghci> a!!0 
1 

Lợi nhuận nhắc 1, giá trị của phần tử đầu tiên, mát mẻ. Bây giờ tôi thêm một giá trị mới vào phía trước của danh sách và cố gắng truy cập vào nó:

ghci> 5:a 
[5,1,2,3] 
ghci> a!!0 
1 

Dường như danh sách các mục không được tái lập chỉ mục. Tôi đã cố gắng nhận được một chỉ số tiêu cực để làm việc và những thứ khác như vậy nhưng trình biên dịch dường như không chấp nhận. Các hướng dẫn tôi đang đọc chỉ cần bỏ qua nó và tôi không thể tìm thấy bất cứ điều gì sử dụng trực tuyến. Làm cách nào để nhận giá trị "5" từ danh sách?

Cảm ơn sự giúp đỡ và xin lỗi nếu đây là câu hỏi rất cơ bản.

+3

Để minh họa điểm Marcin, hãy nhập 'a' tại GHCI và bạn sẽ thấy [1,2,3], vì bạn không thể sửa đổi biến trong Haskell. Để làm rõ mọi thứ, hãy xem xét [các định nghĩa này về biến và có thể gán] (http: //existentialtype.wordpress.com/2012/02/01/words-matter /): Haskell có 'biến' theo nghĩa toán học, nhưng không phải là 'các phép gán' như trong các ngôn ngữ bắt buộc. –

+0

a vẫn còn [1,2,3] sau 5: a.Thera không có tác dụng phụ như đột biến trong lập trình chức năng – nist

+0

Ya Tôi nhận được nó ngay bây giờ, nó chỉ là một suy nghĩ hoàn toàn khác ... haha. Cảm ơn mọi người! – Awesominator

Trả lời

12

Ý tưởng này nằm ở cốt lõi của chức năng lập trình: bạn (thường) không sửa đổi dữ liệu tại chỗ. Vì vậy, bạn không thêm một mục vào danh sách: bạn tạo danh sách mới mà không sửa đổi danh sách cũ.

Điều này cho phép nhiều điều thú vị, chẳng hạn như chia sẻ, vì bạn không bao giờ thay đổi dữ liệu cũ và bạn có thể tiếp tục tham chiếu đến nó. Nhưng nó cũng áp đặt một gánh nặng nếu bạn quen với các mô hình lập trình khác: bạn phải thay đổi cách tiếp cận mọi thứ (và thường bạn phải thay đổi cấu trúc/thuật toán dữ liệu của bạn vì chúng dựa vào việc sửa đổi cấu trúc dữ liệu tại chỗ) .

Trong ví dụ của bạn, chỉ cần cung cấp cho một tên mới vào danh sách cons'ed:

let a = [1, 2, 3] 
let b = 5:a 
7

Sự hiểu lầm của bạn là cơ bản: khuyết điểm không làm thay đổi bất kỳ điều gì.

5:a (trong đó a = [1,2,3]) đánh giá là [5,1,2,3] và đó là những gì thông dịch viên đang hiển thị cho bạn.

2

Lists là không thay đổi:

Prelude> let xs = [1,2,3] 
Prelude> 4:xs 
[4,1,2,3] 
Prelude> xs 
[1,2,3] 
Prelude> let ys = 4:xs 
Prelude> ys 
[4,1,2,3] 

Nếu bạn muốn thay đổi các yếu tố của cấu trúc dữ liệu sử dụng Arrays.

6

Hãy để tôi minh họa với (+) cũng như (:)

Prelude> 4+5 
9 
Prelude> let z = 5 
Prelude> z 
5 
Prelude> 4+z 
9 
Prelude> z 
5 
Prelude> let y = 4+z 
Prelude> y 
9 
Prelude> z 
5 

so

Prelude> let a = [1,2,3] 
Prelude> a 
[1,2,3] 
Prelude> 5:a 
[5,1,2,3] 
Prelude> a 
[1,2,3] 
Prelude> let b = 5:a 
Prelude> b 
[5,1,2,3] 
Prelude> a 
[1,2,3] 

Các ràng buộc được thực hiện bằng 'let' không bao giờ thay đổi nhưng có thể thực hiện những thay đổi mới. Nếu một ràng buộc mới có cùng tên như một ràng buộc cũ thì ràng buộc cũ là "bóng mờ" không bị biến đổi.

Các vấn đề liên quan