Thấu kính chức năng


80

Ai đó có thể giải thích các ống kính chức năng cho tôi không? Đó là một chủ đề khó khăn đáng ngạc nhiên đối với google và tôi đã không đạt được bất kỳ tiến bộ nào. Tất cả những gì tôi biết là chúng cung cấp chức năng get / set tương tự như trong OO.


7
một phần giới thiệu hay về ống kính của Edward Kmett trên YouTube. Các ví dụ có trong Scala, nhưng không quá khó để làm theo.
hammar

Yup, cố gắng để xem những người, nhưng có đủ thời gian trong khi tôi vẫn đang tỉnh táo, không phải là dễ dàng như vậy: P
Masse

2
@Jochen: Các ống kính được mô tả ở đó không thực sự có nhiều điểm chung với các ống kính mà câu hỏi này là về.
sclv

3
Đây là phần giới thiệu hay bằng cách sử dụng hình ảnh: Ống kính trong Hình ảnh .
Debjit

Câu trả lời:


61

Một ống kính bao gồm hai chức năng, một getter và một setter:

data Lens a b = Lens { getter :: a -> b, setter :: b -> a -> a }

Ví dụ: chúng tôi có thể có ống kính cho phần đầu tiên và phần thứ hai của một cặp:

fstLens :: Lens (a, b) a
fstLens = Lens fst $ \x (a, b) -> (x, b)

sndLens :: Lens (a, b) b
sndLens = Lens snd $ \x (a, b) -> (a, x)

Sự tiện lợi thực sự của ống kính là chúng bao gồm:

compose :: Lens b c -> Lens a b -> Lens a c
compose f g = Lens (getter f . getter g) $
                   \c a -> setter g (setter f c (getter g a)) a

Và chúng chuyển đổi một cách máy móc sang các Statechuyển đổi:

lensGet :: MonadState s m => Lens s a -> m a
lensGet = gets . getter

lensSet :: MonadState s m => Lens s b -> b -> m ()
lensSet f = modify . setter f

lensMod :: MonadState s m => Lens s b -> (b -> b) -> m ()
lensMod f g = modify $ setter f =<< g . getter f

(+=) :: (MonadState s m, Num b) => Lens s b -> b -> m ()
f += x = lensMod f (+ x)

Ví dụ soạn thư của bạn không đánh máy. GHC suy luận; Lens aa -> Lens aa -> Lens aa
Masse

Masse: Tôi đã vô tình lật dấu fg.
Apocalisp

Nó vẫn không gõ kiểm tra thành a-> c. Nó suy luận vào soạn :: Lens ab -> Lens aa -> Lens ab
Masse

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.