2011-02-07 16 views
21

Tôi biết rằng TypeSynomymInstances only allows fully applied type synonyms to be used in instance heads, nhưng có vẻ như sẽ thuận tiện nếu tôi có thể sử dụng các từ đồng nghĩa loại được áp dụng theo cách được sử dụng.Tại sao TypeSynonymInstances không cho phép sử dụng các từ đồng nghĩa loại được áp dụng một phần trong các đầu ví dụ?

Ví dụ:

class Example e where 
    thingy :: a -> b -> e a b 

-- legit, but awkward 
newtype FuncWrapper e a b = FuncWrapper { ap :: a -> e a b } 
instance (Example e) => Example (FuncWrapper e) where 
    thingy _ = FuncWrapper . flip thingy 
funcWrapperUse :: (Example e) => e Int String 
funcWrapperUse = thingy 1 "two" `ap` 3 `ap` 4 `ap` 5 

-- not legal, but a little easier to use 
type FuncSynonym e a b = a -> e a b 
instance (Example e) => Example (FuncSynonym e) where 
    thingy _ = flip thingy 
funcSynonymUse :: (Example e) => e Int String 
funcSynonymUse = thingy 1 "two" 3 4 5 
+0

Bạn đã thử '-XTypeSynonymInstances' để chạy phiên bản thứ hai (như GHC đề xuất)? – Landei

+0

@Landel: Nó không thích thực tế là 'FuncSynonym e' không được áp dụng đầy đủ. Vì vậy, câu hỏi của tôi. – rampion

+1

Đây là (liên quan đến) vé [785] (http://ghc.haskell.org/trac/ghc/ticket/785), được đánh dấu là 'wontfix'. –

Trả lời

28

một phần áp dụng từ đồng nghĩa loại không được phép vào Haskell ở tất cả. Một từ đồng nghĩa được áp dụng một phần là một hàm có đầu vào là các kiểu chưa được áp dụng và đầu ra của nó là một kiểu. Ví dụ, đây là một mã hóa của logic boolean:

type True x y = x 
type False x y = y 
type Not b x y = b y x 
type And b1 b2 x y = b1 (b2 x y) y 
type Or b1 b2 x y = b1 x (b2 x y) 

Để quyết định xem hai từ đồng nghĩa loại ứng dụng phần bằng nhau thì kiểm tra loại sẽ phải quyết định xem có chức năng đều bình đẳng. Đây là một vấn đề khó khăn, và nói chung nó là không thể giải quyết được.

+1

Đủ công bằng. Trong ví dụ của tôi, tất cả những gì tôi sử dụng nó là một sự thay thế đơn giản, vì vậy sẽ rất tuyệt nếu có một tùy chọn để cho phép điều đó, nhưng sau đó một lần nữa, tôi không làm việc trên GHC :). Cảm ơn! – rampion

9

Một vấn đề khác với việc cho phép các từ đồng nghĩa loại được áp dụng một phần là chúng sẽ làm cho suy luận kiểu và lựa chọn cá thể về cơ bản là không thể. Ví dụ: giả sử trong ngữ cảnh của một số chương trình tôi muốn sử dụng thingy tại loại Int -> String -> Int -> (Int, String). thingy có kiểu forall a b e. a -> b -> e a b, vì vậy chúng ta có thể thống nhất a với Intb với String, nhưng nếu e được phép trở thành một loại từ đồng nghĩa áp dụng một phần, chúng ta có thể có

e = FuncSynonym (,) 

hoặc

e = FuncSynonym' Int (,) where type FuncSynonym' x f a b = x -> f a b 

hoặc thậm chí

e = Const2 (Int -> (Int, String)) where Const2 a x y = a 

Bài toán suy luận kiểu sẽ trở nên tồi tệ hơn là quyết định sự bình đẳng của các chức năng; nó sẽ yêu cầu xem xét tất cả các chức năng với đầu ra được chỉ định trên một đầu vào cụ thể hoặc các vấn đề tương tự phức tạp hơn (hãy tưởng tượng đơn giản là cố gắng hợp nhất a b với Int).

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