2015-03-18 15 views
5

Trong Haskell, khi sử dụng giải FFI để ràng buộc vào một hàm phân bổ, là nó thích hợp để tránh sử dụng IO khi chức năng nước ngoài phân bổ kiếm và xây dựng một số giá trị và giá trị chỉ phụ thuộc vào các đối số chức năng ?Có cần thiết phải sử dụng IO khi nhập một hàm nước ngoài phân bổ không?

Hãy xem xét các chức năng sau:

/** 
* The foo_create contract: if allocation succeeds, the 
* return value points to a value that depends only on 'x' 
* and 'name', otherwise a null pointer is returned. 
*/ 
foo_t *foo_create(int x, const char *name); 

Nó sẽ là thích hợp để nhập chức năng này theo cách sau? chức năng ràng buộc

newtype Foo = Foo (Ptr Foo) 

foreign import unsafe "foo.h foo_create" 
foo_create :: CInt -> CString -> Ptr Foo 

-mức thấp này sau đó có thể được bao bọc để cung cấp một API đẹp hơn:

makeFoo :: CInt -> CString -> Maybe Foo 
makeFoo x s = 
    let 
    ptr = foo_create x s 
    in 
    if ptr == nullPtr 
     then Nothing 
     else Just (Foo ptr) 

Mặc dù việc phân bổ ảnh hưởng đến thế giới thực, và có hay không nó thành công cũng phụ thuộc vào các thế giới thực, loại hình này mô hình hóa các kết quả có thể là . Hơn nữa, ngay cả các hàm và dữ liệu thuần túy có thể gây ra thời gian chạy Haskell để phân bổ. Vì vậy, nó là hợp lý để tránh IO monad trong các tình huống như thế này?

Trả lời

8

Nếu foo_create trả lại giá trị chỉ phụ thuộc vào các giá trị xname, thì có giá trị trả lại tốt bên ngoài IO. Như bạn nói, việc tạo các giá trị mới bên trong Haskell gây ra phân bổ và chúng không cần phải ở trong IO vì không thể quan sát các địa chỉ bộ nhớ cụ thể được phân bổ bên ngoài IO và cũng không thể quan sát được có phân bổ thành công hay không (nghĩa là chương trình đang hết bộ nhớ) bên ngoài IO.

Tuy nhiên, bạn nói "dù thành công hay không cũng phụ thuộc vào thế giới thực". Trong trường hợp đó, không, nó là một hoạt động hiệu quả cần có kiểu trả về trong IO. Hàm Haskell có loại makeFoo :: CInt -> CString -> Maybe Foo cho biết rằng Maybe FooNothing hoặc Just _ phải phụ thuộc chỉ trên các giá trị của CIntCString. Đây là mỗi bit quan trọng vì giá trị bên trong Just chỉ phụ thuộc vào các đối số.

Nếu có thể gọi hàm có cùng đối số và nhận kết quả khác nhau tùy thuộc vào trạng thái của thế giới thực, thì đó không phải là chức năng và phải là hành động IO.

+0

Điều đó có ý nghĩa. Có vẻ hiển nhiên trong tầm nhìn! Chúc mừng. – frasertweedale

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