Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 正在尝试创建我的typeclass/实例。GHC说:“这是一个很好的例子;无法推断……”;_Haskell_Instance_Typeclass - Fatal编程技术网

Haskell 正在尝试创建我的typeclass/实例。GHC说:“这是一个很好的例子;无法推断……”;

Haskell 正在尝试创建我的typeclass/实例。GHC说:“这是一个很好的例子;无法推断……”;,haskell,instance,typeclass,Haskell,Instance,Typeclass,我试图制作一个简单的图形结构,我写了以下内容。但温室气体引起了错误,我把它堆积在那里。这是我第一次制作自己的typeclass,所以也许我做错了什么。有人能解释一下怎么回事吗 我发现了一个类似的问题,但我认为它不适用于我的情况 这是我收到的错误消息: ***.hs:13:10:Could not deduce (n ~ n1) from the context (Node n) bound by the instance declaration at ***.hs:12:10-40 o

我试图制作一个简单的图形结构,我写了以下内容。但温室气体引起了错误,我把它堆积在那里。这是我第一次制作自己的typeclass,所以也许我做错了什么。有人能解释一下怎么回事吗

我发现了一个类似的问题,但我认为它不适用于我的情况

这是我收到的错误消息:

***.hs:13:10:Could not deduce (n ~ n1)
from the context (Node n)
  bound by the instance declaration
  at ***.hs:12:10-40
or from (Node n1)
  bound by the type signature for
             node :: Node n1 => SimpleLink n -> n1
  at ***.hs:13:3-23
  `n' is a rigid type variable bound by
      the instance declaration
      at ***.hs:12:16
  `n1' is a rigid type variable bound by
       the type signature for node :: Node n1 => SimpleLink n -> n1
       at ***.hs:13:3
Expected type: SimpleLink n -> n1
  Actual type: SimpleLink n -> n
In the expression: simpleLinkNode
In an equation for `node': node = simpleLinkNode

***.hs:21:11:Could not deduce (l ~ l1)
from the context (Link l)
  bound by the instance declaration
  at ***.hs:20:10-40
or from (Link l1)
  bound by the type signature for
             links :: Link l1 => SimpleNode l -> [l1]
  at ***.hs:21:3-25
  `l' is a rigid type variable bound by
      the instance declaration
      at ***.hs:20:16
  `l1' is a rigid type variable bound by
       the type signature for links :: Link l1 => SimpleNode l -> [l1]
       at ***.hs:21:3
Expected type: SimpleNode l -> [l1]
  Actual type: SimpleNode l -> [l]
In the expression: simpleNodeLinks
In an equation for `links': links = simpleNodeLinks
编辑1 我试了一些。 但我不能让它们工作

构造函数类 Get:“'n'未应用于足够的类型参数”

多参数类型类(MPTC) Got:“类内循环声明(通过超类)”

具有函数依赖关系的MPTC Got:“类内循环声明(通过超类)”

目标(编辑2) 我想要实现的是一个有向无环图结构,如下所示(更具体地说,a)


(来源:)

有两种节点(白色圆圈和红色正方形),它们只连接到不同类型的节点,这意味着有两种链接


我想要不同版本的节点和链接,这些节点和链接上连接有数据(数组)。我还想要“香草”DAG,它只有一种类型的节点和链接。但是为了遍历它们,我只需要一个接口就可以了。

类方法的签名

class Link l where
  node :: (Node n) => l -> n

class Node n where
  links :: (Link l) => n -> [l]
假设“调用方想要的任何类型,
节点
响应链接都可以生成它,只要它是
链接
响应节点的成员”,但实现说只能生成一种特定类型的值

它与OOP中的接口有根本的不同,在OOP中,实现决定类型,调用方必须接受类型,这里由调用方决定


您的构造函数类尝试遇到了一些问题。你的类有两个参数,
l
类的
kl
n
类的
kn
(>)
的参数类型必须同时为
*
,即类型类型。因此,要使
ln
成为
(>)
的一个类型良好的参数,
l
必须是一个类型构造函数,它接受一个
kn
类型的参数,并创建一个
*
类型的结果,即

l :: kn -> *
现在您尝试将
节点的结果类型设置为
nl
,这意味着

n :: kl -> *
但在上面我们看到,
kl=kn->*
,这会产生

n :: (kn -> *) -> *
分别
kn=(kn->*)->*
,这是一种无限类型。与无限类型一样,无限类型是不允许的。但是种类推断的实现非常简单,因此编译器假定
l
的参数具有种类
*
,但从
nl
中可以看出
n
具有种类
kl->*
,因此作为
l
的参数,
n
具有错误的种类,它没有应用于足够的类型参数

构造函数类的正常使用是单参数类

class Link l where
    node :: l nod -> nod

class Node n where
    links :: n lin -> [lin]

-- note that we don't have constraints here, because the kinds don't fit

instance Link SimpleLink where
    node = simpleLinkNode

instance Node SimpleNode where
    links = simpleNodeLinks
您必须从数据声明中删除
DatatypeContexts

  • 它们已从语言中删除(可通过扩展提供)
  • 反正也没用
  • 然后进行上述编译。不过,我认为这对你没什么帮助。正如Chris Kuklewicz所观察到的,你的类型追逐他们自己的尾巴,你会把他们当作

    SimpleLink (SimpleNode (SimpleLink (SimpleNode ... {- ad infinitum -})))
    
    对于多参数类,您不能像编译器所说的那样,让每个类都有另一个的需求,这会导致依赖循环(同样,在约束中,您只能将它们与一个参数一起使用

    class Node n => Link l n where ...
    
    这是不正确的,编译器将拒绝(如果循环被破坏)

    你可以通过合并类来解决这个循环

    class NodeLinks l n | l -> n, n -> l where
        node :: l -> n
        links :: n -> l
    
    但是您仍然会遇到这样的问题:您的类型在这方面没有用处


    对不起,我不太了解您的目标,无法提出可行的解决方案。

    类方法的签名

    class Link l where
      node :: (Node n) => l -> n
    
    class Node n where
      links :: (Link l) => n -> [l]
    
    假设“调用方想要的任何类型,
    节点
    响应
    链接都可以生成它,只要它是
    链接
    响应节点的成员”,但实现说只能生成一种特定类型的值

    它与OOP中的接口有根本的不同,在OOP中,实现决定类型,调用方必须接受类型,这里由调用方决定


    您的构造函数类尝试遇到了一些问题。你的类有两个参数,
    l
    类的
    kl
    n
    类的
    kn
    (>)
    的参数类型必须同时为
    *
    ,即类型类型。因此,要使
    ln
    成为
    (>)
    的一个类型良好的参数,
    l
    必须是一个类型构造函数,它接受一个
    kn
    类型的参数,并创建一个
    *
    类型的结果,即

    l :: kn -> *
    
    现在您尝试将
    节点的结果类型设置为
    nl
    ,这意味着

    n :: kl -> *
    
    但在上面我们看到,
    kl=kn->*
    ,这会产生

    n :: (kn -> *) -> *
    
    分别
    kn=(kn->*)->*
    ,这是一种无限类型。与无限类型一样,无限类型是不允许的。但是种类推断的实现非常简单,因此编译器假定
    l
    的参数具有种类
    *
    ,但从
    nl
    中可以看出
    n
    具有种类
    kl->*
    ,因此作为
    l
    的参数,
    n
    具有错误的种类,它没有应用于足够的类型参数

    构造函数类的正常使用是单参数类

    class Link l where
        node :: l nod -> nod
    
    class Node n where
        links :: n lin -> [lin]
    
    -- note that we don't have constraints here, because the kinds don't fit
    
    instance Link SimpleLink where
        node = simpleLinkNode
    
    instance Node SimpleNode where
        links = simpleNodeLinks
    
    您必须从数据声明中删除
    DatatypeContexts

  • 它们已从语言中删除(可通过扩展提供)
  • 反正也没用
  • 然后进行上述编译。不过,我认为这对你没什么帮助。正如Chris Kuklewicz所观察到的,你的类型追逐他们自己的尾巴,你会把他们当作

    SimpleLink (SimpleNode (SimpleLink (SimpleNode ... {- ad infinitum -})))
    
    对于多路径
    class Link l where
      node :: (Node n) => l -> n
    
    instance (Node n) => Link (SimpleLink n) where
      node = simpleLinkNode
    
      `n' is a rigid type variable bound by
          the instance declaration
          at ***.hs:12:16
      `n1' is a rigid type variable bound by
           the type signature for node :: Node n1 => SimpleLink n -> n1
           at ***.hs:13:3
    
    -- Bipartite graph representation, unlabeled edges
    
    -- Data types to hold information about nodes, e.g. ID number
    data VariableVertex = VV { vvID :: Int }  deriving (Show)
    data FactorVertex = FV { fvID :: Int }  deriving (Show)
    
    -- Node holds itself and a list of neighbors of the oppostite type
    data Node selfType adjacentType =
      N { self :: selfType
        , adj :: [Node adjacentType selfType] }
    
    -- A custom Show for Node to prevent infinite output
    instance (Show a, Show b) => Show (Node a b) where
      show (N x ys) = "Node "++ show x ++ " near " ++ show (map self ys)
    
    -- Type aliases for the two node types that will be used
    type VariableNode = Node VariableVertex FactorVertex
    type FactorNode = Node FactorVertex VariableVertex
    
    data FactorGraph = FG [VariableNode] [FactorNode]  deriving (Show)
    
    v1 = N (VV 1) [f1,f2]
    v2 = N (VV 2) [f2]
    v3 = N (VV 3) [f1,f3]
    f1 = N (FV 1) [v1,v3]
    f2 = N (FV 2) [v1,v2]
    f3 = N (FV 3) [v3]
    
    g = FG [v1,v2,v3] [f1,f2,f3]
    
    class NodeClass n where
      adjacent :: n a b -> [n b a]
    
    data Node selfType adjacentType =
      N
      { selfNode :: selfType
      , adjNode :: [Node adjacentType selfType] }
    
    data NodeWithData selfType adjacentType =
      NWD
      { selfNodeWithData :: selfType
      , adjNodeWithData :: [NodeWithData adjacentType selfType]
      , getDataWithData :: [Double]
      }
    
    instance NodeClass Node where
      adjacent = adjNode
    
    instance NodeClass NodeWithData where
      adjacent = adjNodeWithData
    
    data VariableVertex = VV { vvID :: Int }  deriving (Show)
    data FactorVertex = FV { fvID :: Int }  deriving (Show)
    
    type VariableNode = Node VariableVertex FactorVertex
    type FactorNode = Node FactorVertex VariableVertex
    
    type VariableNodeWithData = NodeWithData VariableVertex FactorVertex
    type FactorNodeWithData = NodeWithData FactorVertex VariableVertex