Как проверить, является ли последний элемент списка членом другого списка?

#haskell

#haskell

Вопрос:

У меня возникли некоторые проблемы со списками.

У меня есть следующие списки списков:

 sentence = [['t','h','e'], ['b','o','y'],['i','s'],['h','a','p','p','y']]

shortVowel = [['a'], ['e'], ['y']]
  

Мне нужно создать оператор if, который проверяет 2 вещи:

(1) если элемент x является членом последнего «подсписка» (который, конечно, является последним элементом основного списка),

и (2) если элемент (подсписок) списка shortVowel является последним членом последнего подсписка.

То (1), что я смог сделать с помощью elem 'а' (last sentence)) (проверка, является ли ‘a’ членом ['h','a','p','p','y'] , чем он и является.

(2) — это тот, который я не знаю, как получить.

Например, последний элемент последнего подсписка в sentence является y (от happY). И y также является подсписком в shortVowel списке.

Мне нужно проверить именно это.

Я пробовал некоторые вещи, такие как elem shortVowel (last sentence) , но это не сработало.

Это мой текущий код:

 import Data.List

sentence = [['t','h','e'], ['b','o','y'],['i','s'],['h','a','p','p','y']]

shortVowel = [['a'], ['e'], ['y']]

main =  if ((elem 'а' (last sentence)) || (elem 'о' (last sentence)) || (elem 'у' (last sentence)) amp;amp; (elem shortVowel (last sentence)))
           then putStrLn "A"
        else if (elem 'р' (last sentence))
           then putStrLn "B"
        else putStrLn "C"
  

Комментарии:

1. не удается проверить сейчас, но компилируется ли это? Неправильные типы в elem shortVowel (last sentence) since elem :: a -> [a] -> Bool , но shortVowel :: [[Char]] и last sentence :: [Char] . Кроме того, я думаю, что вы путаете типы. Вы говорите: и y также является подсписком в shortVowel списке y это Char не подсписок. Попробуйте что-то вроде map (== [last (last sentence)]) shortVowel

2. Краткий совет: строковые литералы "abc" внутренне эквивалентны спискам ['a','b','c'] . Таким образом, вы также могли бы написать sentence = ["the", "boy", "is", "happy"] .

3. Что касается вашего вопроса: any Функция полезна в подобных случаях. any f list имеет значение true, если какой -либо list элемент f возвращает значение true при задании в,,. Так, например, any (x -> x > 1) [0,1,2] возвращает True , поскольку существует по крайней мере один элемент, [0,1,2] который удовлетворяет x -> x > 1 .

Ответ №1:

Вместо записи shortVowel = [['a'], ['e'], ['y']] я бы написал shortVowel' = ['a', 'e', 'y'] . Что совпадает с shortVowel' = "aey" . Теперь выполните

 or [x == last $ last sentence | x <- shortVowel']
  

Выше выполняется проверка, является ли какой-либо из элементов в shortVowel последним элементом последнего слова в вашем предложении. Если вы хотите проверить его на наличие всех кратких гласных, выполните

 [(x, x == last $ last sentence) | x <- shortVowel']
  

Ответ №2:

Вот некоторые вещи, которые вы могли бы сделать:

  • Разберитесь с обработкой ошибок. Как список слов, так и само последнее слово могут быть пустыми.

    last является частичной функцией и может аварийно завершать работу во время выполнения.

  • Переместите свою логику в чистую функцию, отдельную от main :: IO .

    Сделайте строку примера параметром функции.

    И разберитесь с извлечением последнего слова из предложения отдельно.

Вот пример этого:

 module Main where

-- | `lastMay [x,y,z] == Just z` and `lastMay [] == Nothing`.
lastMay :: [a] -> Maybe a
lastMay [] = Nothing
lastMay [x] = Just x
lastMay (_:xs) = lastMay xs

-- | `endsWithShortVowel "yay" == True` and `endsWithShortVowel "moo" == False`.
wordEndsWithShortVowel :: String -> Bool
wordEndsWithShortVowel s = case lastMay s of
  Nothing -> False -- No letters in word!
  Just c -> c `elem` "aey"

sentenceEndsWithShortVowel :: [String] -> Bool
sentenceEndsWithShortVowel s = case lastMay s of
  Nothing -> False -- No words in sentence!
  Just w -> wordEndsWithShortVowel w

main :: IO ()
main =
  if sentenceEndsWithShortVowel exampleSentence
    then ...
    else ...

exampleSentence :: [String]
exampleSentence = words "the boy is happy"
  

Тогда, например, становится проще сделать программу восприимчивой к строкам из стандартного ввода:

 main :: IO ()
main = do
  sentence <- words <$> getLine
  if sentenceEndsWithShortVowel sentence
    then ...
    else ...
  

Примечание: Будьте осторожны с уровнями отступов при объединении do и if-then-else .