В чем проблема с этой иглой для стога сена?

Я вдохновился функцией, которую нашел на этом сайте, которая подсчитывает количество слов в строке. Вот код:

      import Data.Text (pack, count)

occurences haystack needles = map function needles
     where 
        packed = pack haystack 
        function needle = (count (pack needle) packed, needle)

Результат команды

      occurences ("Hi how are you") ["Hi", "how" , "are", "yo"] 

дает

      [(1,"Hi"),(1,"how"),(1,"are"),(1,"yo")]

Тогда как это должно дать

      [(1,"Hi"),(1,"how"),(1,"are"),(0,"yo")]

Так как yo! = Вы

Как я могу изменить свой метод, чтобы он работал должным образом?

Ps: Еще одно решение, которое я пробовал, которое допускает ту же ошибку, - это:

      import Control.Arrow ((&&&))
import Data.List (isPrefixOf, tails)

yourFunction :: Eq a => [a] -> [[a]] -> [(Int, [a])]
yourFunction haystack = map (count &&& id)
  where count needle = length . filter (needle `isPrefixOf`) . tails $ haystack

1 ответ

Решение

Вы проверяете строгие подстроки, когда вам кажется, что вам нужно проверить полные слова. Haskell включаетфункция, которая разбивает строку на отдельные слова. Вы можете использовать это для создания функции, которая делает то, что вы хотите:

      import Control.Arrow ((&&&))

occursWord :: String -> [String] -> [(Int, String)]
occursWord haystack = map (count &&& id)
    where wordlist = words haystack
          count n = length . filter (== n) $ wordlist

Потому что words работает только вместо [a], тип occurrences должен быть специализированным, чтобы работать только с Stringс. (Это имеет смысл, однако, поскольку список чисел не может содержать пробелов для разделения. Даниэль Вагнер упоминает в комментариях, что есть также <tcode id="365020"></tcode> который действует на Text тип.)

Результат этой функции:

      > occursWord "Hi how are you" ["Hi","how","are","yo"]
[(1,"Hi"),(1,"how"),(1,"are"),(0,"yo")]
Другие вопросы по тегам