我正在尝试编写一个函数来比较两个给定图中节点的度数列表,以进行同构的充分性测试,但我注意到以下代码抛出了与以下类型相关的错误degs:
import Data.List
degreeNumbers :: (Eq a) => Graph a -> [Int]
degreeNumbers g = ...
isoByDegree :: (Eq a, Eq b) => Graph a -> Graph b -> Bool
isoByDegree g1 g2 = degs g1 == degs g2
where degs = sort . degreeNumbers
Run Code Online (Sandbox Code Playgroud)
即使我尝试degs使用类似的显式声明进行绑定
where degs = (sort . degreeNumbers) :: (Eq c) => Graph c -> [Int]
Run Code Online (Sandbox Code Playgroud)
它仍然表示它期待一种Graph a而不是Graph b应用于它g2.当然,有一个简单的解决方案
isoByDegree g1 g2 = (sort . degreeNumbers) g1 == (sort . degreeNumbers) g2
Run Code Online (Sandbox Code Playgroud)
但我想知道绑定方法出了什么问题.
这是由可怕的单态性限制引起的.禁用它NoMonomorphismRestriction.
{-# LANGUAGE NoMonomorphismRestriction #-}
import Data.List
type Graph a = [a]
degreeNumbers :: (Eq a) => Graph a -> [Int]
degreeNumbers g = undefined
isoByDegree :: (Eq a, Eq b) => Graph a -> Graph b -> Bool
isoByDegree g1 g2 = degs g1 == degs g2
where degs = sort . degreeNumbers
Run Code Online (Sandbox Code Playgroud)
如果您不想禁用monomorhism限制,则可以为degs显式签名提供声明.
isoByDegree :: (Eq a, Eq b) => Graph a -> Graph b -> Bool
isoByDegree g1 g2 = degs g1 == degs g2
where
degs :: (Eq c) => Graph c -> [Int]
degs = sort . degreeNumbers
Run Code Online (Sandbox Code Playgroud)
在声明的右侧添加签名只会在右侧为表达式提供一个显式类型(与推断的类型相同); 它不会使degs声明多态.