Có một mô hình rất phổ biến trong việc triển khai nhiều chức năng trong nền tảng haskell làm phiền tôi, nhưng tôi không thể tìm thấy lời giải thích. Đó là về việc sử dụng các hàm lồng nhau để tối ưu hóa.Nền tảng Haskell: chức năng lồng nhau và tối ưu hóa
Lý do cho hàm lồng nhau trong mệnh đề khi chúng nhắm đến đệ quy đuôi là rất rõ ràng đối với tôi (như trong length), nhưng mục đích là gì khi hàm bên trong có cùng kiểu như hàm cấp cao nhất ? Nó xảy ra, trong ví dụ, trong nhiều chức năng của Data.Set
module, giống như một sau:
-- | /O(log n)/. Is the element in the set?
member :: Ord a => a -> Set a -> Bool
member = go
where
STRICT_1_OF_2(go)
go _ Tip = False
go x (Bin _ y l r) = case compare x y of
LT -> go x l
GT -> go x r
EQ -> True
#if __GLASGOW_HASKELL__ >= 700
{-# INLINABLE member #-}
#else
{-# INLINE member #-}
#endif
tôi nghi ngờ nó có thể có cái gì để làm với memoization, nhưng tôi không chắc chắn.
chỉnh sửa: Kể từ dave4420 cho thấy tính nghiêm minh, đây là định nghĩa cho STRICT_1_OF_2
vĩ mô có thể được tìm thấy trong các mô-đun tương tự:
-- Use macros to define strictness of functions.
-- STRICT_x_OF_y denotes an y-ary function strict in the x-th parameter.
-- We do not use BangPatterns, because they are not in any standard and we
-- want the compilers to be compiled by as many compilers as possible.
#define STRICT_1_OF_2(fn) fn arg _ | arg `seq` False = undefined
Tôi hiểu thế nào điều này công trình vĩ mô, tuy nhiên tôi vẫn không thấy lý do tại sao go
cùng với STRICT_1_OF_2(go)
không được di chuyển ở cấp cao nhất thay vì member
.
Có thể nó không phải vì tối ưu hóa, mà đơn giản chỉ vì lựa chọn phong cách?
chỉnh sửa 2: Tôi thêm phần INLINABLE
và INLINE
từ các mô-đun bộ. Tôi đã không nghĩ rằng họ có thể có một cái gì đó để làm với nó ở cái nhìn đầu tiên.
Tôi nghi ngờ đó là điều cần làm với phân tích nghiêm ngặt: trình biên dịch dự kiến suy luận rằng đối số đầu tiên cho 'thành viên' phải được đánh giá nhưng đối số đầu tiên cho' go' sẽ luôn được đánh giá. Nhưng tôi không chắc chắn. – dave4420
@ dave4420: Cảm ơn bạn đã đề xuất. Tôi cập nhật câu hỏi của tôi với một số thông tin thêm về mức độ nghiêm ngặt của chức năng, tôi hy vọng điều này sẽ giúp. –
Tôi nghĩ rằng đó hoàn toàn là một vấn đề về phong cách. Nhưng bạn có thể kiếm được vài phút bằng cách cho phép 'x' được tự do trong' go'. Tôi không thích phong cách mà trong đó điều này đã được viết bằng ong, vì nó có vẻ ngụ ý rằng x được seq: ed trong mỗi lần lặp lại. Ngoài ra, nó làm cho thành viên nghiêm ngặt trong 'x' khi nó không phải là (nhưng đó là nhỏ). – augustss