我正在尝试使用查询显示表中的几列。但是我收到一条错误消息:
* Couldn't match type `Char' with `[Char]'
Expected type: [[[Field]]]
Actual type: [[[Char]]]
* In the second argument of `mapMaybe', namely
`(map transpose (table))'
In the expression:
mapMaybe (elemIndex columns) (map transpose (table))
In an equation for `project':
project columns table@(header : _)
= mapMaybe (elemIndex columns) (map transpose (table))
我的Haskell代码如下:
project columns table@(header : _)
= mapMaybe (elemIndex columns) (map transpose (table))
table
属于Table
型,即[Row]
或[[Field]]
。Field
是String
的同义词。
让我们首先查看我们正在使用的函数的签名:
elemIndex
具有以下签名:
elemIndex :: Eq a => a -> [a] -> Maybe Int
mapMaybe
具有以下签名:
mapMaybe :: (a -> Maybe b) -> [a] -> [b]
然后我们可以根据其参数columns
(从名称中我期望的类型为[Field]
)来专门化elemIndex
的类型
elemIndex :: [Field] -> [[Field]] -> Maybe Int
因此:
elemIndex columns :: [[Field]] -> Maybe Int
然后,让我们根据其第一个参数对mapMaybe
进行相同的专用化,elemIndex columns
:
mapMaybe :: ([[Field]] -> Maybe Int) -> [[[Field]]] -> Int
因此:
mapMaybe (elemIndex columns) :: [[[Field]]] -> Int
但我希望根据你所说的,table
是一个Table
,你说的是一个[Row]
,这是一个[[Field]]
,不能填补所需[[[Field]]]
的角色。
那么为什么会这样呢?我认为你在滥用elemIndex
.elemIndex
是一个函数,给定一个类型为a
的值和一个类型[a]
的列表,查找列表中该值第一次出现的索引,并返回该值Just
,如果根本不存在,则返回Nothing
:
elemIndex 5 [1, 2, 3, 4, 5]
> 4
但是,看起来您正在尝试为其提供类型为a
的值和类型为[[a]]
的列表列表,并获取第一个子列表的索引以该值开头:
elemIndex' 5 [[1, 5], [2, 4], [3, 3], [4, 2], [5, 1]]
> 4
这个函数在标准库(或我知道的任何库)中不存在。我建议使用函数elemIndexBy
:
elemIndexBy :: (a -> Boolean) -> [a] -> Maybe Int
elemIndexBy fun list = go list 0
where go [] _ = Nothing
go (x:xs) ix
| fun x = Just ix
| otherwise = go xs $ succ ix
elemIndexBy ((5 ==) . head) [[1, 5], [2, 4], [3, 3], [4, 2], [5, 1]]
> 4