使用 Filter 删除 Nothing 案例时,涉及空列表的案例不会编译

Cases involving empty lists does not compile when using Filter to remove Nothing cases

对于一项作业,我必须编写一个函数,该函数在 Maybe 个实例的列表中使用 filter,删除所有值为 Nothing 的实例。我们应该确保该函数使用 Hspec 工作。

使用 Data.Maybe (isJust):

来处理包含 运行 前后元素的案例很简单
onlyJust :: [Maybe a] -> [Maybe a]
onlyJust = filter isJust

但是,一旦我尝试将该函数应用于测试用例,例如

it "produces the list []" $
    onlyJust [Nothing, Nothing] `shouldBe` []

it "produces the list []" $
    onlyJust [] `shouldBe` []

测试套件文件无法编译,出现类型不明确的错误。

• Ambiguous type variable ‘a0’ arising from a use of ‘shouldBe’
  prevents the constraint ‘(Show a0)’ from being solved.
  Probable fix: use a type annotation to specify what ‘a0’ should be.

我已尝试按照错误消息的提示添加类型注释,但找不到与函数本身的类型约束相匹配的注释。对于后一个测试用例,我还尝试通过添加一个空用例来修改函数:

onlyJust :: [Maybe a] -> [Maybe a]
onlyJust [] = []
onlyJust l = filter isJust l

但错误仍然存​​在。我是否掩盖了一个明显的类型注释来解决这个问题,或者函数的编写方式是否存在缺陷,这意味着它无法处理输出空列表或将一个空列表作为输入?

对于 onlyJust [Nothing, Nothing] shouldBe [] 它不知道为 Maybe a 中的 a 选择什么值,因此出现错误。您可以添加类型提示,例如:

onlyJust ([Nothing, Nothing] <strong>:: [Maybe Int]</strong>) `shouldBe` []

空列表也一样:

onlyJust ([] <strong>:: [Maybe Int]</strong>) `shouldBe` []

请注意,已经有一个 catMaybes :: [Maybe a] -> [a] 过滤掉 Nothing 并从 Just … 数据构造函数中解包项目。