我有以下函数,它只从列表中返回奇数
oddsOnly :: Integral a => [a] -> [a]
oddsOnly [] = []
oddsOnly (x:xs)
|odd x = x : oddsOnly xs
|otherwise = oddsOnly xs
Run Code Online (Sandbox Code Playgroud)
我的问题是关于使用的目的
积分 a =>
实际上不可能用这样的类型声明来实现这样的功能
赔率 :: [a] -> [a]
据我所知,偶数和奇数函数都在标准Prelude库中,为什么简化的声明不起作用?
提前致谢
为什么简化的声明不起作用?
因为你无法判断一个字符串是否是奇数。或者浮点数是否为奇数。通常,无法判断任何类型的值是否a为奇数,因为可能没有为该类型定义奇数的概念。
但是,它是为Integral类型定义的,因此您必须指定它a是Integral。
就 Haskell 而言,仅odd适用于Integrals:
Prelude> :t odd
odd :: Integral a => a -> Bool
Run Code Online (Sandbox Code Playgroud)
因此,您必须向它传递一个类型为 的值Integral。
的签名odd和even是odd :: Integral a => a -> Bool和even :: Integral a => a -> Bool分别。所以这些包含一个Integral a 类型约束 [Haskell-wiki]。
类型约束与定义它的位置无关。它指定只为类型的子集定义函数。仅对于属于Integraltypeclass 的类型,您可以使用该函数。整型类型是指定 ℤ、so Int、Int64、Word8、Integer、 … 类型的子集的类型。odd并且even对Floats、Strings、Chars 等没有多大意义。那是什么意思?
通过指定Integral a =>类型约束,您可以指定此函数只能处理类似整数的项目。
请注意,您可以filter :: (a -> Bool) -> [a] -> [a]在此处使用仅保留奇数:
oddsOnly :: Integral a => [a] -> [a]
oddsOnly = filter oddRun Code Online (Sandbox Code Playgroud)