我正在处理使用t类型元素列表的函数。这意味着列表可以是整数列表,也可以是字符串或字符列表。但是我不明白为什么(Eq t)必须在类型签名中。举个例子
belong :: (Eq t) => t -> [t] -> Bool belong e [] = False belong e (x:xs) | e == x = True | otherwise = belong e xs
--为什么(等式t)在签名中?
tpgth1q71#
将列表元素x与项e、e == x进行比较。这是一个测试这两个t类型的项是否相等的操作。要做到这一点,项目本身必须是可比较的,因为你不能只是比较两个任意的东西。你的函数在t类型中是 * 参数多态的 *,t是一个无约束的类型变量,所以类型可以是任何东西,一般来说不可能推理出该类型上可能的态射。函数签名中的类约束(Eq t) =>告诉类型t应该属于类型类Eq。它 * 表达了一个要求 *,即列表中的项目和你要比较的项目必须是可比较的。
x
e
e == x
t
(Eq t) =>
Eq
class Eq a where (==) :: a -> a -> Bool ...
类型类Eq定义了具有a -> a -> Bool类型的函数==,它就像一个“接口”,所有实现这个类型类的类型都将拥有它。==函数的确切实现将根据t所用具体类型的Eq类型类的 * 示例 * 来确定;这是一个特殊多态性的例子,其中每个具体值都采用一个类型类,因为它已经被赋予了这个类型类的单独定义。
a -> a -> Bool
==
9udxz4iz2#
在“guard"中,您可以写入e == x。现在,为了检查两个项是否相等,我们使用(==) :: Eq a => a -> a -> Bool。并不是每个类型都可以使用这个函数,正如类型签名已经说过的那样,需要将该类型作为Eq类型类的示例,以定义两个项是否相等。然而,该函数可以简化为:
(==) :: Eq a => a -> a -> Bool
belong :: Eq t => t -> [t] -> Bool belong e [] = False belong e (x:xs) = e == x || belong e xs
或使用any在任何Foldable上工作:
any
Foldable
belong :: (Eq t, Foldable f) => t -> f t -> Bool belong = any . (==)
由于base-4.8,您的函数已经在Prelude中存在此泛型签名:elem :: (Eq a, Foldable f) => a -> f a -> Bool。
base-4.8
Prelude
elem :: (Eq a, Foldable f) => a -> f a -> Bool
2条答案
按热度按时间tpgth1q71#
将列表元素
x
与项e
、e == x
进行比较。这是一个测试这两个t
类型的项是否相等的操作。要做到这一点,项目本身必须是可比较的,因为你不能只是比较两个任意的东西。你的函数在t
类型中是 * 参数多态的 *,t
是一个无约束的类型变量,所以类型可以是任何东西,一般来说不可能推理出该类型上可能的态射。函数签名中的类约束
(Eq t) =>
告诉类型t
应该属于类型类Eq
。它 * 表达了一个要求 *,即列表中的项目和你要比较的项目必须是可比较的。类型类
Eq
定义了具有a -> a -> Bool
类型的函数==
,它就像一个“接口”,所有实现这个类型类的类型都将拥有它。==
函数的确切实现将根据t
所用具体类型的Eq
类型类的 * 示例 * 来确定;这是一个特殊多态性的例子,其中每个具体值都采用一个类型类,因为它已经被赋予了这个类型类的单独定义。9udxz4iz2#
在“guard"中,您可以写入
e == x
。现在,为了检查两个项是否相等,我们使用(==) :: Eq a => a -> a -> Bool
。并不是每个类型都可以使用这个函数,正如类型签名已经说过的那样,需要将该类型作为Eq
类型类的示例,以定义两个项是否相等。然而,该函数可以简化为:
或使用
any
在任何Foldable
上工作:由于
base-4.8
,您的函数已经在Prelude
中存在此泛型签名:elem :: (Eq a, Foldable f) => a -> f a -> Bool
。