Несколько 'Just x' для 'case MaybeVal of' в haskell

Делать несколько дел 'Just' в haskell, например, в порядке. в

findElement :: Ord a => a -> [a] -> Maybe Int
findElement element list = case (listToMaybe list) of
                             Nothing -> Nothing
                             Just element -> Just 0
                             Just _ -> Just (1 + (fromMaybe 0 (findElement element (tail list))))

Кажется, работает только один из случаев Just (который когда-либо ставится первым). Ожидаемый результат

> findElement 4 [1,2,3,4,5,6,7,8]
Just 3
> findElement 3 [5,6,4,7,8,0]
Nothing
> findElement 4 []
Nothing
> findElement 'o' "Hello world"
Just 4
> findElement 'x' ""
Nothing

1 ответ

Решение

Нет, это не работает таким образом, вам нужен такой охранник:

findElement element list = 
   case (listToMaybe list) of
      Nothing               -> ...
      Just e | e == element -> ...
      Just _                -> ...

Проблема в том, что каждая переменная, встречающаяся в шаблонах, привязывается к соответствующему значению. Если ты пишешь Just element это не относится к предыдущей переменной element но вместо этого вводит новую локальную переменную, должна как e в моем коде выше.

Итак, сопоставление с образцом на Just element очень похоже на

 findElement element list = 
    let element = ...
    in ...

В последней строке предыдущая переменная element становится "затененным" при последующем связывании.

Чтобы избежать этой ошибки, я настоятельно рекомендую включить предупреждения с -Wall: это указало бы на опасные тени.

Другие вопросы по тегам