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.
- 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. - Định nghĩa không giá trị như
varNum
yêu cầu ràng buộc đơn sắc qua<-
trong mộtdo
. Đ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ứcdo
. - 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ụngcase
thay vì phương trình. - 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)
+1 để đặt câu hỏi Tôi không đủ thông minh để đóng góp cho – delnan
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ó? –
@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