2009-04-03 30 views
6

Cabbage.hs:Tại sao biến loại này không rõ ràng?

module Cabbage where 
class Cabbage a 
    where foo :: a -> String  -- the parameter is only present for its type, 
           -- the parameter value will be ignored 
     bar :: String -> a 
quux :: Cabbage a => String -> a 
quux s = bar (s ++ foo (undefined :: a)) 

Khi tôi biên dịch (với GHC) tôi nhận được thông báo lỗi này:

Cabbage.hs:7:19: 
    Ambiguous type variable `a' in the constraint: 
     `Cabbage a' arising from a use of `foo' at Cabbage.hs:7:19-38 
    Probable fix: add a type signature that fixes these type variable(s) 

Tôi không hiểu tại sao a là mơ hồ. Chắc chắn a trong dòng 7 giống với a trong dòng 6? Làm thế nào để sửa lỗi này?

Ngoài ra, có cách nào tốt hơn để khai báo hằng số cho từng trường hợp không?

Trả lời

11

Sử dụng biến loại có phạm vi, bạn có thể cho GHC biết rằng undefined :: a phải giống nhau (nếu không a chỉ là viết tắt của forall a. a). sau đó biến kiểu scoped phải rõ ràng forall trình độ:

{-# LANGUAGE ScopedTypeVariables #-} 
module Cabbage where 
class Cabbage a 
    where foo :: a -> String  -- the parameter is only present for its type, 
           -- the parameter value will be ignored 
     bar :: String -> a 
quux :: forall a. Cabbage a => String -> a 
quux s = bar (s ++ foo (undefined :: a)) 
2

Vấn đề là Haskell không biết trường hợp nào là Cabbagefoo tương ứng với đó. Cho đến nay như tôi biết, nó không phù hợp với a trong (undefined :: a) với a trong quux :: Cabbage a => String -> a

Giả sử đó là những gì bạn muốn, bạn có thể làm điều này:

quux :: Cabbage a => String -> a 
quux s = result 
    where result = bar (s ++ foo result) 

này gắn foo và bar với nhau để nó sử dụng cùng một ví dụ cho cả hai, và vì bạn không thực sự cần giá trị của đầu vào cho foo, nó đáy. Tôi không biết một cách tốt hơn để làm cho mỗi ví dụ hằng số mặc dù. Hy vọng rằng một người khác sẽ đến cùng với ai.

2

bạn có thể trích xuất ra phần đa hình là một hàm

quux :: Cabbage a => String -> a 
quux s = quux' undefined 
    where quux' :: Cabbage a => a -> a 
      quux' x = bar (s ++ foo x) 
Các vấn đề liên quan