Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.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:“约束中的非类型变量参数:Eq位”和“没有使用'=''的(Eq位)实例”_Haskell - Fatal编程技术网

Haskell:“约束中的非类型变量参数:Eq位”和“没有使用'=''的(Eq位)实例”

Haskell:“约束中的非类型变量参数:Eq位”和“没有使用'=''的(Eq位)实例”,haskell,Haskell,此代码导致以下错误消息: data Bit = One | Zero deriving Show type Bits = [Bit] bits2String :: Bits -> String bits2String [] = "" bits2String (x:xs) | x == One = "1" ++ bits2String xs | x == Zero = "0" ++ bits2String xs

此代码导致以下错误消息:

data Bit = One 
         | Zero
         deriving Show

type Bits = [Bit]

bits2String :: Bits -> String
bits2String [] = ""
bits2String (x:xs) | x == One = "1" ++ bits2String xs
                   | x == Zero = "0" ++ bits2String xs
对于这个错误,你可以找到很多解决方法。他们总是说你需要像这样添加Eq:

No instance for (Eq Bit) arising drom a use of '=='
但这对我不起作用,并导致以下错误

bits2String :: (Eq Bit) => Bits -> String
bits2String [] = ""
bits2String (x:xs) | x == One = "1" ++ bits2String xs
                   | x == Zero = "0" ++ bits2String xs
{LANGUAGE FlexibleContexts-}也不起作用。

您使用了x==0,因此使用了函数,但您没有将Bit作为Eq的实例。您可以将其添加到派生子句中,这样Haskell就可以为您的Bit数据类型自动实现Eq的实例:

Non type-variable argument in the constraint: Eq Bit
(Use FlexibleContexts to permit this)
在这里,我们利用将函数应用于原始列表中的每个项目,从而将项目列表转换为另一个列表。由于位是位的列表,字符串是字符的列表,因此我们可以将每个位映射到一个字符,以分别获得0和1的“0”和“1”字符串。

您使用x==0,函数也是如此,但您没有将位作为Eq的实例。您可以将其添加到派生子句中,这样Haskell可以为您的位数据类型自动实现Eq实例:

Non type-variable argument in the constraint: Eq Bit
(Use FlexibleContexts to permit this)

在这里,我们利用将函数应用于原始列表中的每个项目,从而将项目列表转换为另一个列表。由于位是位的列表,字符串是字符的列表,因此我们可以将每个位映射到一个字符,以分别获得0和1的“0”和“1”字符串。

原始错误消息是关键消息:

bits2String :: Bits -> String
bits2String = map f
    where f Zero = '0'
          f One = '1'
这是因为您正在使用==运算符,该运算符仅适用于Eq typeclass的实例,而您还没有给出这样的实例

不过这很容易解决。例如,您可以轻松地手动提供实例:

No instance for (Eq Bit) arising drom a use of '=='
不过我不建议你这么做。您可以要求Haskell通过向类型定义添加派生子句来为您生成确切的实例。事实上,您已经在使用Eq,因此您可以将Eq添加到要派生的实例列表中:

instance Eq Bit where
    One == One = True
    Zero == Zero = True
    _ == _ = False
一般来说,添加此实例是一个好主意,因为您可能需要在某个点比较位是否相等,特别是在处理它们的列表时-许多列表函数(如elem)依赖于其成员的Eq实例

但您可以通过在两个数据构造函数上进行模式匹配,将bits2String函数重写为完全不需要Eq实例:

data Bit = One 
     | Zero
     deriving (Show, Eq) 
事实上,您基本上已经在这里重新实现了map函数,因此我可能要做的是定义:

bits2String :: Bits -> String
bits2String [] = ""
bits2String (One:xs) = "1" ++ bits2String xs
bits2String (Zero:xs) = "0" ++ bits2String xs
特别是因为它是一种通用的效用函数,你很可能想要用于其他事情

然后

bitToChar :: Bit -> Char
bitToChar Zero = '0'
bitToChar One = '1'

所有这些都不需要Eq实例,但出于我提到的原因,推导Eq实例可能是个好主意

原始错误消息是关键消息:

bits2String :: Bits -> String
bits2String = map f
    where f Zero = '0'
          f One = '1'
这是因为您正在使用==运算符,该运算符仅适用于Eq typeclass的实例,而您还没有给出这样的实例

不过这很容易解决。例如,您可以轻松地手动提供实例:

No instance for (Eq Bit) arising drom a use of '=='
不过我不建议你这么做。您可以要求Haskell通过向类型定义添加派生子句来为您生成确切的实例。事实上,您已经在使用Eq,因此您可以将Eq添加到要派生的实例列表中:

instance Eq Bit where
    One == One = True
    Zero == Zero = True
    _ == _ = False
一般来说,添加此实例是一个好主意,因为您可能需要在某个点比较位是否相等,特别是在处理它们的列表时-许多列表函数(如elem)依赖于其成员的Eq实例

但您可以通过在两个数据构造函数上进行模式匹配,将bits2String函数重写为完全不需要Eq实例:

data Bit = One 
     | Zero
     deriving (Show, Eq) 
事实上,您基本上已经在这里重新实现了map函数,因此我可能要做的是定义:

bits2String :: Bits -> String
bits2String [] = ""
bits2String (One:xs) = "1" ++ bits2String xs
bits2String (Zero:xs) = "0" ++ bits2String xs
特别是因为它是一种通用的效用函数,你很可能想要用于其他事情

然后

bitToChar :: Bit -> Char
bitToChar Zero = '0'
bitToChar One = '1'

所有这些都不需要Eq实例,但出于我提到的原因,推导Eq实例可能是个好主意

我并不奇怪在我打字的时候出现了另一个答案,但当我们说了几乎完全相同的话时,我感到有点遗憾,落后你超过10分钟…@RobinZigmond:也许我领先了一步,谁知道呢:我不奇怪在我打字的时候出现了另一个答案,但是,当我们说了几乎完全相同的话时,我感到有点遗憾,落后你超过10分钟…@RobinZigmond:也许我领先了一步,谁知道呢: