Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.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推断/显式类型的Where绑定_Haskell_Types - Fatal编程技术网

Haskell推断/显式类型的Where绑定

Haskell推断/显式类型的Where绑定,haskell,types,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
类型相关的错误:

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
即使我试图用一个显式声明绑定
degs
,比如

where degs = (sort . degreeNumbers) :: (Eq c) => Graph c -> [Int]
它仍然表示,在应用于
g2
时,它期待的是一种
图形a
而不是
图形b
。当然,有一个简单的解决方案

isoByDegree g1 g2 = (sort . degreeNumbers) g1 == (sort . degreeNumbers) g2

但是我想知道绑定方法到底出了什么问题。

这是由恐惧造成的。使用
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
如果不想禁用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

在声明的右侧添加签名只会给右侧的表达式一个显式类型(这与推断的类型相同);它不会使
degs
声明多态。

因为您将类型声明放在等式的右侧,而不是左侧,Haskell仍然使用类型推断来确定
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

谢谢,这两种解决方案都很有见地。就在我以为自己在我的基本应用程序领域遇到了所有难以捉摸的绊脚石的时候!这些MR问题在这里频繁出现,因此我认为GHC至少应该在默认情况下发出警告(假设默认情况下关闭MR是不可取的)。例如,对于类型错误,如果表达式包含一些单态推断项,GHC应输出有关这些项的警告。