Làm thế nào để bạn nhận và sử dụng loại phụ thuộc từ một loại lớp với các phụ thuộc chức năng?Làm thế nào để bạn nhận và sử dụng loại phụ thuộc từ một loại lớp với các phụ thuộc chức năng?
Để làm rõ và đưa ra một ví dụ về nỗ lực mới nhất của tôi (hạn chế tối đa từ mã thực tế tôi đang viết):
class Identifiable a b | a -> b where -- if you know a, you know b
idOf :: a -> b
instance Identifiable Int Int where
idOf a = a
f :: Identifiable Int b => Int -> [b] -- Does ghc infer b from the functional dependency used in Identifiable, and the instance?
f a = [5 :: Int]
Nhưng GHC không suy ra b, có vẻ như, vì nó in lỗi này:
Couldn't match expected type ‘b’ with actual type ‘Int’
‘b’ is a rigid type variable bound by
the type signature for f :: Identifiable Int b => Int -> [b]
at src/main.hs:57:6
Relevant bindings include
f :: Int -> [b] (bound at src/main.hs:58:1)
In the expression: 5 :: Int
In the expression: [5 :: Int]
In an equation for ‘f’: f a = [5 :: Int]
Đối với bối cảnh, đây là một ví dụ ít hạn chế tối đa:
data Graph a where
Graph :: (Identifiable a b) => GraphImpl b -> Graph a
getImpl :: Identifiable a b => Graph a -> GraphImpl b
getImpl (Graph impl) = impl
Cách giải quyết ở đây sẽ có thêm b as type arg để đồ thị:
data Graph a b | a -> b where
Graph :: (Identifiable a b) => GraphImpl b -> Graph a
Bối cảnh đầy đủ: Tôi có một Graph
của đơn vị mà mỗi người đều có một id, mỗi thực thể được gán cho 1 nút. Bạn có thể tra cứu một nút theo thực thể. Tôi cũng có một Graph'
bao gồm các nút (có thể được gán một thực thể), và để tra cứu một nút bạn cần cung cấp id của nút, đó là một Int. Graph
sử dụng Graph'
nội bộ. Tôi có một số IdMap
để ánh xạ các id của các thực thể thành các id của các nút trong Graph'
. Đây là Graph
định nghĩa của tôi:
data Graph a where
Graph :: (Identifiable a b) => {
_idMap :: IdMap b,
_nextVertexId :: Int,
_graph :: Graph' a
} -> Graph a
trả lời: Sử dụng gia đình loại, xem Daniel Wagner's answer. Để xem toàn bộ câu chuyện, hãy xem Reid Barton's answer.
@Carsten Cảm ơn, 'idOf' thực sự làm việc. Đối với các ràng buộc, tôi đã cố gắng để xem nếu có một tính năng trong haskell để 'phù hợp với mô hình' một loại với một lớp học. Đối với ví dụ thứ hai, có cách nào để làm cho nó hoạt động mà không cần sử dụng 'Đồ thị a b | a -> b', và/hoặc là có một lý do từ quan điểm thiết kế để làm việc sau không? – timdiels