Q:

Haskell Inferred/Explicit Types of Where Bindings

I'm trying to write a function that compares the lists of degrees of the nodes in two given graphs for a sufficiency test of isomorphism, but I noticed the following code throws errors related to the type of 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

Even when I try to bind degs with an explicit declaration like
where degs = (sort . degreeNumbers) :: (Eq c) => Graph c -> [Int]

it still says it's expecting a type of Graph a rather than Graph b upon being applied to g2. Of course, there's the plain solution of
isoByDegree g1 g2 = (sort . degreeNumbers) g1 == (sort . degreeNumbers) g2

but I'm wondering what's going wrong with the binding approach.

A:

This is caused by the dreaded monomorphism restriction. Disable it with 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

If you don't want to disable the monomorhism restriction, you can give the declaration for degs an explicit signature. 
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

Adding a signature to the right hand side of the declaration only gives the expression on the right hand side an explicit type (which is the same as what would be inferred); it doesn't make the degs declaration polymorphic.

