2010-08-04 11 views
16

Như Moggi đã đề xuất cách đây 20 năm, không gian chức năng hiệu quả -> của các ngôn ngữ như ML có thể được phân tách thành không gian chức năng tiêu chuẩn => cộng với một đơn nguyên mạnh T để ghi lại hiệu ứng.Làm cách nào để nhúng phần lõi của một ngôn ngữ có không gian chức năng hiệu quả (như ML) vào Haskell?

A -> B phân hủy để A => (T B)

Bây giờ, Haskell hỗ trợ monads, bao gồm một đơn nguyên IO xuất hiện đủ cho các hiệu ứng trong ML, và nó có một không gian chức năng có chứa => (nhưng cũng bao gồm các chức năng một phần). Vì vậy, chúng ta sẽ có thể dịch một đoạn đáng kể của ML vào Haskell thông qua sự phân hủy này. Về lý thuyết tôi nghĩ rằng điều này hoạt động.

Câu hỏi của tôi là liệu việc nhúng như thế này có thể thực tế không: có thể thiết kế thư viện Haskell cho phép lập trình trong Haskell theo kiểu không quá xa ML? Và nếu như vậy hiệu suất sẽ như thế nào?

Tiêu chí của tôi cho "thực tế" là mã ML hiện có với việc sử dụng rộng rãi các hiệu ứng có thể tương đối dễ dàng được phiên âm thành Haskell qua nhúng, bao gồm cả các trường hợp phức tạp liên quan đến các hàm bậc cao hơn.

Để thực hiện điều này cụ thể, nỗ lực của riêng tôi tại phiên âm như vậy thông qua việc nhúng dưới đây. Chức năng chính là một phiên mã của một số mã ML đơn giản mà tạo ra 5 tên biến riêng biệt. Thay vì sử dụng phân tích trực tiếp, phiên bản của tôi nâng các chức năng để chúng đánh giá các đối số của chúng - các định nghĩa trước main là một thư viện nhỏ bao gồm cả các tài nguyên gốc. Điều này làm việc ổn, nhưng một số khía cạnh không hoàn toàn thỏa đáng.

  1. Có quá nhiều tiếng ồn cú pháp để chèn giá trị vào tính toán qua val. Có các phiên bản chức năng chưa được sửa đổi (như rdV) sẽ giúp điều này, với chi phí yêu cầu các chức năng này được xác định.
  2. Định nghĩa không giá trị như varNum yêu cầu ràng buộc đơn sắc qua <- trong một do. Điều này sau đó buộc bất kỳ định nghĩa nào phụ thuộc vào chúng cũng có cùng biểu thức do.
  3. Dường như toàn bộ chương trình có thể kết thúc bằng một biểu thức lớn do. Đây là cách chương trình ML thường được xem xét, nhưng trong Haskell nó không được hỗ trợ khá tốt - ví dụ, bạn buộc phải sử dụng case thay vì phương trình.
  4. Tôi đoán sẽ có một số sự lười biếng mặc dù luồng đơn IO trong suốt. Cho rằng chương trình ML sẽ được thiết kế để đánh giá nghiêm ngặt, có lẽ nên loại bỏ sự lười biếng. Tôi không chắc chắn cách tốt nhất để làm điều này là mặc dù.

Vì vậy, bất kỳ lời khuyên nào về việc cải thiện điều này, hoặc cách tiếp cận tốt hơn bằng cách sử dụng cùng một phân tích hoặc thậm chí các cách khác nhau để đạt được cùng một mục tiêu lập trình rộng rãi trong Haskell. (Nó không phải là tôi không thích phong cách của Haskell, nó chỉ là tôi muốn để có thể lập bản đồ đang ML hiện một cách dễ dàng.)

import Data.IORef 
import Control.Monad 

val :: Monad m => a -> m a 
val = return 

ref = join . liftM newIORef 
rdV = readIORef         -- Unlifted, hence takes a value 
(!=) r x = do { rr <- r; xx <- x; writeIORef rr xx } 

(.+),(.-) :: IO Int -> IO Int -> IO Int 
((.+),(.-)) = (liftM2(+), liftM2(-)) 

(.:) :: IO a -> IO [a] -> IO [a] 
(.:) = liftM2(:) 
showIO :: Show a => IO a -> IO String 
showIO = liftM show 

main = do 
    varNum <- ref (val 0) 
    let newVar = (=<<) $ \() -> val varNum != (rdV varNum .+ val 1) >> 
           val 'v' .: (showIO (rdV varNum)) 
    let gen = (=<<) $ \n -> case n of 0 -> return [] 
             nn -> (newVar $ val()) .: (gen (val n .- val 1)) 
    gen (val 5) 
+8

+1 để đặt câu hỏi Tôi không đủ thông minh để đóng góp cho – delnan

+0

Với bản chất của các câu hỏi và câu trả lời bạn đã đăng, bạn sẽ xem xét [thêm hỗ trợ của bạn ở đây] (http://area51.stackexchange.com/ đề xuất/8766/lý thuyết-máy tính-khoa học) nếu bạn chưa có? –

+2

@camccann Thú vị - Tôi đoán tôi đã thử nghiệm và phát hiện ra rằng Stack Overflow rất hữu ích cho các câu hỏi như vậy (với điều này có thể đẩy các giới hạn, hoặc chỉ là khó trả lời). Tôi phần nào bị phân chia trên trang web TCS: Tôi thường không muốn tách biệt lý thuyết khỏi thực tiễn cũng như thuật ngữ "lý thuyết". Câu hỏi này liên quan đến monads, nhưng tôi chủ yếu hỏi về một cái gì đó của việc sử dụng thực tế. Cá nhân tôi có thể hạnh phúc hơn với thẻ TCS trên SO. Nói chung tôi nghĩ rằng gộp những thứ lại với nhau và sau đó chiếu các tập con thông qua thẻ là một mô hình tốt hơn khi không có đường phân chia rõ ràng. – RD1

Trả lời

3

Here 's một cách có thể, bởi SIGFPE. Nó không bao gồm lambdas, nhưng có vẻ như nó có thể được mở rộng cho họ.

+0

Một vài kỹ thuật thú vị mà tôi có thể thử sử dụng. Đó là một ý tưởng tương tự như trong đoạn mã tôi đã đưa ra (không đáng ngạc nhiên vì Andrzej Filinski và tôi đã học cùng nhau tại CMU). Ngoài ra, tôi muốn phân loại rằng nhúng dưới "công trình trong lý thuyết" hơn là "làm việc trong thực tế". Plus, tôi đoán tôi muốn tránh các mẫu cho bây giờ và xem những gì tốt đẹp embeddings là có thể mà không cần hack cú pháp. – RD1