Điều đó tùy thuộc. Nếu bạn biên dịch mà không cần tối ưu hóa, chắc chắn là một hình phạt không sử dụng như-mô hình, nhưng nếu bạn biên dịch đoạn mã sau
module Test where
merge1 :: Ord a => [a] -> [a] -> [a]
merge1 [] bs = bs
merge1 as [] = as
merge1 (a:as) (b:bs) = case compare a b of
LT -> a : merge1 as (b:bs)
EQ -> a : merge1 as bs
GT -> b : merge1 (a:as) bs
merge2 :: Ord a => [a] -> [a] -> [a]
merge2 [] bs = bs
merge2 as [] = as
merge2 [email protected](a:as) [email protected](b:bs) = case compare a b of
LT -> a : merge2 as ys
EQ -> a : merge2 as bs
GT -> b : merge2 xs bs
với -O2
và -ddump-simpl
, và sau rất nhiều chỉnh sửa đúng đắn, đổi tên của biến, tước của siêu dữ liệu và chú thích, và thủ đoạn khác nhau, bạn có thể đi đến một cái gì đó giống như
merge2_2 :: Ord a => a -> [a] -> [a] -> [a]
merge2_2 = \ ordInst x y z -> case z of _ {
[] -> (x:y);
(w:v) -> case compare ordInst x w of _ {
LT -> x : merge2_1 ordInst y w v;
EQ -> x : merge2 ordInst y v;
GT -> w : merge2_2 ordInst x y v
}
}
merge2_1 :: Ord a => [a] -> a -> [a] -> [a]
merge2_1 = \ ordInst x y z -> case x of _ {
[] -> (y:z);
(w:v) -> case compare ordInst w y of _ {
LT -> w : merge2_1 ordInst v y z;
EQ -> w : merge2 ordInst v z;
GT -> y : merge2_2 ordInst w v z
}
}
merge2 :: Ord a => [a] -> [a] -> [a]
merge2 = \ ordInst x y -> case x of wild {
[] -> y;
(w:v) -> case y of _ {
[] -> wild;
(z:zs) -> case compare ordInst w z of _ {
LT -> w : merge2_1 ordInst v z zs;
EQ -> w : merge2 ordInst v zs;
GT -> z : merge2_2 ordInst w v zs
}
}
}
merge1_2 :: Ord a => a -> [a] -> [a] -> [a]
merge1_2 = \ ordInst x y z -> case z of _ {
[] -> (x:y);
(w:v) -> case compare ordInst x w of _ {
LT -> x : merge1_1 ordInst y w v;
EQ -> x : merge1 ordInst y v;
GT -> w : merge1_2 ordInst x y v
}
}
merge1_1 :: Ord a => [a] -> a -> [a] -> [a]
merge1_1 = \ ordInst x y z -> case x of _ {
[] -> (y:z);
(w:v) -> case compare ordInst w y of _ {
LT -> w : merge1_1 ordInst v y z;
EQ -> w : merge1 ordInst v z;
GT -> y : merge1_2 ordInst w v z
}
}
merge1 :: Ord a => [a] -> [a] -> [a]
merge1 = \ ordInst x y -> case x of wild {
[] -> y;
(w:v) -> case y of _ {
[] -> wild;
(z:zs) -> case compare ordInst w z of _ {
LT -> w : merge1_1 ordInst v z zs;
EQ -> w : merge1 ordInst v zs;
GT -> z : merge1_2 ordInst w v zs
}
}
}
nào, sau khi so sánh với một công cụ diffing, nói với tôi rằng sự khác biệt duy nhất giữa hai khái niệm này là những con số ở hai đầu của merge
tên hàm. Vì vậy, có, sau khi áp dụng tối ưu hóa, GHC có thể tìm ra các mẫu này cho bạn, ít nhất là trong trường hợp danh sách. Tuy nhiên, tôi vẫn khuyên bạn nên sử dụng chúng bởi vì luôn có các trường hợp cạnh, và nếu bạn sử dụng chúng thì bạn không cần phải tin tưởng trình biên dịch để làm một cái gì đó phức tạp. Điều này cũng có nghĩa là ngay cả khi tối ưu hóa không được bật, mã của bạn sẽ vẫn có tối ưu hóa đó trong đó. Nó có vẻ giống như một thay đổi nhỏ, nhưng nếu chức năng này kết thúc trong một vòng lặp bên trong hoặc các cấu trúc bạn đang làm việc trên là rất lớn nó có thể có một tác động hiệu suất đáng kể. Ngoài ra, tôi thấy rằng đối với các nhà xây dựng có số lượng lớn các trường, thường thì thuận tiện hơn khi có tên để tham khảo biểu mẫu "được xây dựng".
Here's the full core dump if you're interested. Về cơ bản, tôi bắt đầu bằng cách nối các dòng với nhau để chiếm ít không gian hơn, sau đó loại bỏ các ký hiệu loại, loại bỏ các tên module đủ điều kiện, tất cả các chú thích [Something]
, đổi tên những thứ như merge2_$smerge2
thành merge2_2
, xóa tất cả chữ ký kiểu địa phương, sau đó bắt đầu đổi tên sử dụng tính năng con trỏ tuyệt vời của Sublime Text. Tôi bắt đầu với những cái tên kiểu, đổi tên họ tất cả để chỉ a
, sau đó đổi tên thành tên biến để x
, y
, z
, w
, v
, và zs
(Tôi sáng tạo, không phải là tôi?), Làm tất cả các ứng dụng của :
infix nhà điều hành, loại bỏ các khu vực Rec
, và một vài chi tiết về kiểu dáng sau này tôi đã nhận được kết quả bạn nhìn thấy ở trên.
Tôi sử dụng chúng mọi lúc. Nó làm cho nó rõ ràng rằng bạn chỉ sử dụng đầu vào như là. – Dan