如何从具有函数依赖关系的类型类中获取和使用依赖类型?如何从具有函数依赖关系的类型类中获取和使用依赖类型?
澄清,给我的最新尝试的例子(从实际的代码最小化我在写):
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]
但GHC不能由此推断B,现在看来,它打印此错误:
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]
为背景,这里有一个不太最小例如:
data Graph a where
Graph :: (Identifiable a b) => GraphImpl b -> Graph a
getImpl :: Identifiable a b => Graph a -> GraphImpl b
getImpl (Graph impl) = impl
解决方法在这里是添加B中类型ARG到图:
data Graph a b | a -> b where
Graph :: (Identifiable a b) => GraphImpl b -> Graph a
完整的上下文:我有各自具有一个id实体的Graph
,每个实体被分配到1个节点。您可以按实体查找节点。我也有一个Graph'
,它由节点(可以分配一个实体)和查找节点,你需要提供节点的id,这是一个Int。 Graph
内部使用Graph'
。我有一个IdMap
,它将实体的ID映射到Graph'
中的节点的ID。这是我的Graph
定义:
data Graph a where
Graph :: (Identifiable a b) => {
_idMap :: IdMap b,
_nextVertexId :: Int,
_graph :: Graph' a
} -> Graph a
答:使用类型的家庭,看到Daniel Wagner's answer。 有关完整的故事,请参阅Reid Barton's answer。
@Carsten谢谢'idOf'确实奏效。至于约束,我试图查看haskell中是否有一个功能与类“模式匹配”。对于第二个例子,有没有办法让它工作而不使用'Graph a b | a - > b',和/或从设计的角度来看是否有理由去做后者? – timdiels