何时在Haskell类型声明中使用Eq?

何时在Haskell类型声明中使用Eq?,haskell,Haskell,我的理解是,当您使用=或\=比较一个函数参数时,应该将Eq…添加到函数的类型声明中。但是,GHCi表示,以下内容还需要Eq类型类: take' _ [] = [] take' 0 _ = [] take' n (x:xs) = x : take' (n - 1) xs %% Needs the following type class %% take' :: (Eq t, Num t) => t -> [a] -> [a] 为什么它要求将Eq t添加到类型声明中,即使n参数

我的理解是,当您使用
=
\=
比较一个函数参数时,应该将
Eq…
添加到函数的类型声明中。但是,GHCi表示,以下内容还需要
Eq
类型类:

take' _ [] = []
take' 0 _ = []
take' n (x:xs) = x : take' (n - 1) xs

%% Needs the following type class
%% take' :: (Eq t, Num t) => t -> [a] -> [a]

为什么它要求将
Eq t
添加到类型声明中,即使
n
参数从未与任何东西进行比较?

模式匹配
take'0=…
是等式检查的语法糖,即

take' _ [] = []
take' n _
    | n==0  = []
take' n (x:xs) = x : take' (n - 1) xs
因此,如果希望计数器参数是多态的,则需要
Eq t
。还有
Num t
,因此您可以获得值
0
,并计算
n-1

实际上,除了
Int
之外,没有太多令人信服的理由将
take
用于任何类型,因此标准版本在该参数中根本不是多态的:

take :: Int -> [a] -> [a]

由于
Int
被称为
Eq
Num
的实例,模式匹配
take'0.=…
是等式检查的语法糖,即

take' _ [] = []
take' n _
    | n==0  = []
take' n (x:xs) = x : take' (n - 1) xs
因此,如果希望计数器参数是多态的,则需要
Eq t
。还有
Num t
,因此您可以获得值
0
,并计算
n-1

实际上,除了
Int
之外,没有太多令人信服的理由将
take
用于任何类型,因此标准版本在该参数中根本不是多态的:

take :: Int -> [a] -> [a]

由于
Int
被称为
Eq
Num

的实例,这很有意义,谢谢。因为列表可以是任何类型的,所以
take
是否仍然是多态的类型
take::Int->[a]->[a]
,因为列表可以是任何类型的?是的,但在数字类型中不是多态的。我能问一下为什么
Num t
是必需的,而不是说
integral t
?因为如果要向其中传递float/double,该函数将无法工作。这仅仅是因为Haskell无法识别它不能与浮点/双精度运算一起工作吗?好吧,它可以与
浮点
一起工作,只是对于非整数运算它会表现得很愚蠢——但编译器不知道什么是愚蠢的。如果你想让函数继续运行,如果参数是分数的,并且在递归中变为负数,该怎么办?你是对的,这是没有意义的,如果你让它成为数字多态的,你应该需要
Integral
。但正如我所说的,更好的是,你应该使用一个具体的数字类型,比如
Int
(或者,完全是键入声音),这很有意义,谢谢。因为列表可以是任何类型的,所以
take
是否仍然是多态的类型
take::Int->[a]->[a]
,因为列表可以是任何类型的?是的,但在数字类型中不是多态的。我能问一下为什么
Num t
是必需的,而不是说
integral t
?因为如果要向其中传递float/double,该函数将无法工作。这仅仅是因为Haskell无法识别它不能与浮点/双精度运算一起工作吗?好吧,它可以与
浮点
一起工作,只是对于非整数运算它会表现得很愚蠢——但编译器不知道什么是愚蠢的。如果你想让函数继续运行,如果参数是分数的,并且在递归中变为负数,该怎么办?你是对的,这是没有意义的,如果你让它成为数字多态的,你应该需要
Integral
。但正如我所说的,更好的是,你应该使用一个具体的数字类型,比如
Int
(或者,完全是type-sound,)。