元素在列表中的位置

Position of element in List

我试图在给定其 ID 的列表中获取元素的索引。这就是我所拥有的:

type alias Id = Int  

posInList : Id -> List (Id, ItemModel) -> Int
posInList id list =
  if List.isEmpty list then 
      -1
  else 
    if (List.head list).fst == id then
      0
    else 
      if posInList id (List.tail list) == -1 then
        -1
      else
        posInList id (List.tail list) + 1

我从找到的方案代码中得到了 here(有 7 票回答)。

当我编译代码时出现两个错误:

我该如何解决这个问题?或者有更简单的解决方案吗?

更新:用 Maybe

试了一下
posInList : Id -> Maybe List (Id, ItemModel) -> Int
posInList id list =
  case list of
    Nothing -> -1
    Just a -> 
      case (List.head a) of
        Just b -> 
          if b.fst == id then 
            0
          else
            case (List.tail a) of
              Nothing -> -1
              Just c -> (posInList id (Just c)) + 1
        Nothing -> -1

我想我已经接近了,但我无法解决这个错误:

Just cMaybe List 类型,但它与 Maybe 有什么冲突? 我想到了类型注释,所以我像这样添加了括号:

posInList : Id -> Maybe (List (Id, ItemModel)) -> Int

但后来我得到:

现在我一无所知,从未见过这样的错误。

你看过以下内容吗:

Right way to forcibly convert Maybe a to a in Elm, failing clearly for Nothings

首先,将其分解为更简单的 indexOf 函数可能会有所帮助,以避免必须处理您正在使用的特定元组模型。这使它更干净,更可重用。

我们将 indexOf 定义为:

indexOf : a -> List a -> Maybe Int
indexOf el list =
  let
    indexOf' list' index =
      case list' of
        [] ->
          Nothing
        (x::xs) ->
          if x == el then
            Just index
          else
            indexOf' xs (index + 1)
  in
    indexOf' list 0

这里没有什么特别的,只是模式匹配和递归调用。子函数 indexOf' 用于跟踪当前索引。

现在我们有了一个通用的 indexOf 函数,它可以用于任何可比较的类型,而不仅仅是整数。

接下来我们需要挤入你的List (Id, ItemModel)类型的列表。这是我们可以在 map 函数中使用 fst 的地方,创建一个 Id 的列表。

posInList : Id -> List (Id, ItemModel) -> Int
posInList id list =
  case indexOf id (List.map fst list) of
    Nothing ->
      -1
    Just index ->
       index

您最初的实现是 returning -1,以防找不到某些东西,但我认为 return a Maybe Int 会更符合习惯。这将使使用该库的任何其他人清楚地了解您的意图。