2013-07-07 27 views
21

Haskell 2010 có đảm bảo nối chuỗi ký tự String vào thời gian biên dịch không?Haskell có nối chuỗi ký tự chuỗi vào thời gian biên dịch không?

Nếu tôi có

"This is a " ++ 
"very long String that " ++ 
"spans several lines" 

không trình biên dịch điều trị nó như

"This is a very long String that spans several lines" 

Tôi muốn giữ lại dòng nguồn của tôi dài hơn 80 ký tự nếu có thể, nhưng tôi không muốn giới thiệu thời gian chạy không hiệu quả.

Trả lời

16

Sử dụng một khoảng cách-một chuỗi một hoặc nhiều ký tự khoảng trắng giữa dấu xồ nguợc:

"This is a \ 
\very long String that \ 
\spans several lines" 

Tương đương zero-width là \&, hữu ích để tách thoát số từ ký tự chữ số:

"\123\&45" == "{45" 
"\12345" == "〹" 
19

Haskell 2010 đảm bảo rằng nó tương đương với giá trị tương đương với chuỗi đã hợp nhất, nhưng không có gì để nói về cách biên dịch. Thật dễ dàng để kiểm tra với công cụ ghc-core.

-- Test.hs 
main = putStrLn $ "Hello " ++ "world" 

và khi chúng ta chạy ghc-core Test.hs

[1 of 1] Compiling Main    (Test.hs, Test.o) 

==================== Tidy Core ==================== 
Result size of Tidy Core = {terms: 19, types: 23, coercions: 9} 

main2 :: [Char] 
[GblId, 
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=False, 
     ConLike=False, WorkFree=False, Expandable=False, 
     Guidance=IF_ARGS [] 60 0}] 
main2 = unpackCString# "Hello world" 

... 

và thấy rằng chuỗi đã được sáp nhập vào ngôn ngữ trung gian Core.


Chỉnh sửa: Để làm nổi bật thỏa thuận của tôi với các câu trả lời khác, không đảm bảo trình biên dịch sẽ thực hiện tất cả các chuỗi. Việc tuân thủ đặc tả Haskell không hàm ý nhiều về cách mọi thứ được biên dịch.

+0

cẩn thận về việc sử dụng "dump cốt lõi" để in mã lõi trung gian :-) – David

+0

Tôi có thể đã truyền đạt ý thức nhân tạo về cách dễ dàng nhìn trộm lõi và học cách mọi thứ đang hoạt động ... nhưng! Tôi thường thấy nó không quá khó khăn. Chỉ cần nản lòng lúc đầu. –

19

Bảo hành Haskell 2010 có nối được các chuỗi ký tự trong thời gian biên dịch không?

số

hiệu quả Run-thời gian là xa phạm vi của Haskell2010. Chúng tôi không muốn cấm triển khai thử nghiệm chỉ vì chúng chậm.

Ngoài ra, hãy nói những gì nên được thực hiện trong thời gian biên dịch sẽ gây rắc rối cho người phiên dịch, chẳng hạn như Hugs.

Cuối cùng, hữu ích khi cung cấp một số quyền tự do cho người triển khai. Có lẽ trong một số trường hợp kỳ lạ nó sẽ được thực sự nhanh hơn không để precompute chuỗi?

Haskell 2010 nói về thời gian biên dịch chỉ trong ngữ cảnh lỗi. (Ví dụ: lỗi loại được đảm bảo là thời gian biên dịch.)

4

Tôi không đảm bảo điều này. Có thể có các trình biên dịch như ghc thực hiện tối ưu hóa này nhưng không có tiêu chuẩn gì để bảo quản điều này. Vì vậy, nó có thể xảy ra rằng trong một phiên bản trong tương lai tối ưu hóa này có thể không xảy ra.

Tại sao bạn không sử dụng Mẫu Haskell nếu bạn thực sự muốn đảm bảo rằng nó được thực hiện tại thời gian biên dịch.Theo gương được thử nghiệm trên GHC nhưng tôi nghĩ bạn có thể làm cho nó làm việc trên các trình biên dịch khác quá:

Trong một tập tin mô-đun bạn có thể có một mã như thế này

module Concat where 
import Language.Haskell.TH 

(<++>) :: String -> String -> ExpQ 
(<++>) x y = stringE (x ++ y) 

Sau đó, trong tập tin mà bạn cần để thực sự làm biên dịch thời gian nối

{-# LANGUAGE TemplateHaskell #-} 
import Concat 

f = $("This is a very long string" <++> 
     "which spans over several lines") 

Bạn thậm chí có thể kiểm tra trong GHC bằng cách sử dụng -ddump-splices rằng chuỗi nối được tạo ra tại thời gian biên dịch.

+5

Ngoài ra còn có tài liệu [Rất nhiều tài liệu ở đây] (http://www.haskell.org/haskellwiki/Poor_man's_here_document) sử dụng các mối nối thay vì các toán tử nội tuyến. –

+0

@tel Cảm ơn. Điều đó có vẻ tốt hơn nhiều để sử dụng. – Satvik

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