Xét đoạn mã sauGADT kiểu lập luận không được sử dụng để giải quyết typeclass
data Foo f where
Foo :: Foo Int
class DynFoo t where
dynFoo :: Foo f -> Foo t
instance DynFoo Int where
dynFoo Foo = Foo
obsFoo :: (DynFoo t) => Foo f -> Foo t
obsFoo = dynFoo
useDynFoo :: Foo f -> Int
useDynFoo (obsFoo -> Foo) = 1
Trận đấu pattern trong useDynFoo
nên hạn chế việc sử dụng các obsFoo
có loại Foo f -> Foo Int
, mà nên gây ra nó để tìm kiếm một thể hiện của DynFoo Int
. Tuy nhiên, thay vào đó, nó tìm kiếm một thể hiện của DynFoo t
cho không rõ t
và tự nhiên không thành công.
No instance for (DynFoo t0) arising from a use of ‘obsFoo’
The type variable ‘t0’ is ambiguous
Tuy nhiên, nếu tôi thay đổi định nghĩa của useDynFoo
để
useDynFoo :: Foo f -> Int
useDynFoo (obsFoo -> (Foo :: Foo Int)) = 1
Sau đó, nó đột nhiên hoạt động, mặc dù loại chữ ký của tôi là hoàn toàn không cần thiết.
Vì vậy, tại sao điều này xảy ra và làm cách nào tôi có thể sử dụng obsFoo
mà không cần phải cung cấp chữ ký loại?
Câu trả lời chỉ dành cho liên kết này, cần được mở rộng. Ngay bây giờ nó không giải thích nhiều. – chi
Bạn cũng nên tránh liên kết đến "mới nhất", thích một phiên bản tài liệu cụ thể. – dfeuer