Haskell推断/显式绑定的类型

Fer*_*yll 2 haskell types

我正在尝试编写一个函数来比较两个给定图中节点的度数列表,以进行同构的充分性测试,但我注意到以下代码抛出了与以下类型相关的错误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)

但我想知道绑定方法出了什么问题.

Cir*_*dec 6

这是由可怕的单态性限制引起的.禁用它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声明多态.