haskell - No instance of (Eq ([a] -> [a])) when pattern matching a list of functions
问题描述
Consider the following code:
step :: [[a] -> [a]] -> [[a]] -> [[a]]
step (f:fs) xss
| (fs == []) = yss
| otherwise = step fs yss
where yss = map f xss
It throws the following error:
No instance for (Eq ([a] -> [a])) arising from a use of ‘==’
(maybe you haven't applied a function to enough arguments?)
|
3 | | (fs == []) = res
| ^^^^^^^^
fs
should be either a list of functions or an empty list, so why is the compiler trying to make a function out of it?
解决方案
You can only check lists for equality when their elements can be checked for equality (instances of Eq
). You might think this is nonsense, since you're comparing to the empty list, so the value of the elements don't matter. But typewise, Haskell sees all these lists as just lists, and it's unknown if it's empty, so it can't let the comparison happen.
Luckily, there's a function just for this: null :: [a] -> Bool
, that checks if a list is empty:
step :: [[a] -> [a]] -> [[a]] -> [[a]]
step (f:fs) xss
| null fs = yss
| otherwise = step fs yss
where yss = map f xss
(disclaimer: null
is actually defined for all foldables, but for our purposes you can treat it as a list function)
You can also use a pattern guard for pattern matching (since pattern matching can recognize empty lists):
step :: [[a] -> [a]] -> [[a]] -> [[a]]
step (f:fs) xss
| [] <- fs = yss
| otherwise = step fs yss
where yss = map f xss
推荐阅读
- python - 如何在以下情况下访问变量的值
- c# - 使用按钮将小数相加
- javascript - 如何在另一个中包含 html 文件以避免重复代码?
- python - 使用 dlib 进行多目标跟踪
- blazor - 如何在 Blazor 服务器端应用程序中处理异步取消
- python - 我必须复制和粘贴一个包吗?
- firebase - 如何使用 Firebase 在 Flutter 中登录用户的电子邮件
- google-cloud-platform - 使用 Terraform 和 Google Cloud Platform 在云中创建端点
- macos - SwiftUI NSVisualEffectView 看起来不透明?
- java - 如果函数参数的类型相同,为什么在 Java 中强制转换函数调用的两个参数是多余的?