Haskell - 检查列表中的所有项是否大于1

Bol*_*boa 2 haskell function list

如果所有项都大于1,我需要返回布尔值True,否则返回False.这是我的尝试......

greaterOne :: Ord a=>a->Bool
greaterOne x = x > 1

checkLis :: Ord a=>[a]->Bool
checkLis [] = True
checkLis (x:xs)
    | greaterOne x = checkLis xs
    | otherwise = False
Run Code Online (Sandbox Code Playgroud)

这是我得到的错误,我一直试图解决它,但无济于事......

Could not deduce (Num a) arising from the literal ‘1’
from the context (Ord a)
  bound by the type signature for greaterOne :: Ord a => a -> Bool
  at pract.hs:23:15-28
Possible fix:
  add (Num a) to the context of
    the type signature for greaterOne :: Ord a => a -> Bool
In the second argument of ‘(>)’, namely ‘1’
In the expression: x > 1
In an equation for ‘greaterOne’: greaterOne x = x > 1
Run Code Online (Sandbox Code Playgroud)

the*_*eye 5

暂时,只考虑这个表达,

x > 1
Run Code Online (Sandbox Code Playgroud)

我们肯定知道,这1是一个数字,我们需要将其与之比较x并返回结果.但是我们不知道它的类型x.如果x实际上是一个String怎么办?然后表达式将失败.但是Haskell的类型系统很强大,它会感觉到这里的混乱,并要求你手动修复它.它甚至为你提供了一个提示,

Possible fix:
  add (Num a) to the context of
    the type signature for greaterOne :: Ord a => a -> Bool
Run Code Online (Sandbox Code Playgroud)

所以,你要做的就是明确指定这a是一个类的实例Num,正如GHC所建议的那样

checkLis :: Ord a => Num a => [a] -> Bool
checkLis [] = True
......
greaterOne :: Ord a => Num a => a -> Bool
greaterOne x = x > 1
Run Code Online (Sandbox Code Playgroud)

现在,我们说,a不仅仅是一个Ordered数据类型,而且它实际上是类Num.


您实际上可以使用内置函数all来执行此操作.

> all greaterOne [2, 2, 3]
True
> all greaterOne [1, 2, 3]
False
Run Code Online (Sandbox Code Playgroud)

all函数检查作为第一个参数传递的函数是否True为列表中的每个元素求值.


实际上我们可以只使用部分表达式来做同样的事情,就像这样

Prelude> all (> 1) [2, 2, 3]
True
Prelude> all (> 1) [1, 2, 3]
False
Run Code Online (Sandbox Code Playgroud)