2012-01-04 44 views
30

Làm cách nào để nhập rõ ràng các trường hợp kiểu chữ? Ngoài ra, làm cách nào để tôi thực hiện việc này với việc nhập đủ điều kiện?Trường hợp nhập rõ ràng

Hiện nay, tôi đang làm

import Control.Monad.Error() 

để import dụ đơn nguyên mà tôi có thể sử dụng cho (Either String). Trước đây, tôi đã sử dụng

import Control.Monad.Error 

Tôi không hài lòng với một trong hai vì trường hợp Monad được nhập hoàn toàn.

Trả lời

45

Không có khả năng kiểm soát việc nhập khẩu các cá thể là một trong những sự đánh đổi mà hệ thống kiểu chữ Haskell tạo ra. Dưới đây là một ví dụ trong một phương ngữ Haskell giả định mà bạn có thể:

Foo.hs:

module Foo where 

data Foo = FooA | FooB deriving (Eq, Ord) 

Bar.hs:

module Bar (myMap) where 

import Data.Map (Map) 
import qualified Data.Map as Map 

import Foo 

myMap :: Map Foo Int 
myMap = Map.singleton FooA 42 

Baz.hs:

module Baz where 

import Data.Map (Map) 
import qualified Data.Map as Map 

import Foo hiding (instance Ord Foo) 
import Bar (myMap) 

instance Ord Foo where 
    FooA > FooB = True 
    FooB > FooA = False 

ouch :: Map Foo Int 
ouch = Map.insert FooB 42 myMap 

Yikes! Tập hợp myMap được tạo với đúng instance Ord Foo, nhưng nó được kết hợp với bản đồ được tạo bằng khác nhau, ví dụ mâu thuẫn.

Có khả năng thực hiện việc này sẽ vi phạm giả thiết về thế giới mở của Haskell. Thật không may, tôi không biết một tài nguyên tập trung, tốt để học về nó. Điều này section of RWH có thể hữu ích (tôi đã tìm kiếm "giả định thế giới mở haskell").

+0

Bản đồ, không phải là Bộ. Ví dụ hay, +1. –

+0

@DanielFischer: Cố định, cảm ơn :) – ehird

+3

Có nghĩa là, nếu muốn đi con đường đó, bạn sẽ phải tạo ra các thể hiện hạng nhất, sao cho một Bản đồ có thể mang theo từ điển Ord của nó xung quanh? –

7

Bạn không thể. Các trường hợp luôn được xuất khẩu ngầm và do đó bạn không thể nhập chúng một cách rõ ràng. Nhân tiện, ví dụ Monad của Either e hiện nay là Control.Monad.Instances.

2

Mặc dù câu trả lời thường đúng sẽ là "không, bạn không thể", tôi đề nghị giải pháp khủng khiếp này:

copy + dán

Hãy xem mã nguồn thư viện cho các mong muốn mô-đun và sao chép/dán các khai báo, nhập khẩu và định nghĩa dữ liệu cần thiết vào mã của riêng bạn. Không sao chép các trường hợp bạn không muốn.

Tùy thuộc vào sự cố trong tay, ghc type system extensionsOverlappingInstances hoặc IncoherentInstances có thể là giải pháp thay thế, mặc dù điều này có thể sẽ không giải quyết được sự cố với thư viện base.

+1

Tôi nghĩ rằng Matt muốn có thể nói một cái gì đó như 'nhập khẩu Foo (dụ Bar Baz)' hơn 'nhập khẩu Foo (Bar, ẩn dụ Baz)'. –

+0

@DanielFischer - vâng, vâng. Tuy nhiên, nếu không thể thực hiện điều đó, nếu bạn hoàn toàn cần làm một điều như vậy, copy + paste là giải pháp "kế hoạch B" duy nhất mà tôi có thể nghĩ đến. Nó cũng có thể là tốt đẹp để thêm một bình luận như '{- # ThisInstanceTrumps # -}' để buộc GHC sử dụng cá thể của bạn thay vì bất kỳ trường hợp nào nó có thể chọn khác. –

+4

Wow, đây thực sự là một gợi ý khủng khiếp. Điều duy nhất bạn bỏ ra là sử dụng 'unsafeCoerce' để tương tác giữa các bản gốc và các định nghĩa sao chép/dán của bạn. –

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