Подтвердить что ты не робот

Простой подсчет слов в haskell

Это моя первая программа haskell! "wordCount" принимает список слов и возвращает кортеж с каждым нечувствительным к регистру словам в сочетании с его количеством использования. Любые предложения по улучшению как считываемости кода, так и производительности?

import List;
import Char;
uniqueCountIn ns xs = map (\x -> length (filter (==x) xs)) ns
nubl (xs) = nub (map (map toLower) xs) -- to lowercase
wordCount ws =  zip ns (uniqueCountIn ns ws)
   where ns = nubl ws
4b9b3361

Ответ 1

Поздравляем с вашей первой программой!

Для чистоты: потеряйте точки с запятой. Вместо этого используйте новые имена иерархических модулей (Data.List, Data.Char). Добавьте сигнатуры типов. По мере того, как вы становитесь более комфортно с композицией функций, eta сокращайте свои определения функций (удалите самые правые аргументы). например.

nubl :: [String] -> [String]
nubl = nub . map (map toLower)

Если вы хотите быть очень строгим, используйте явные списки импорта:

import Data.List (nub) 
import Data.Char (toLower)

Для производительности: используйте Data.Map для хранения ассоциаций вместо nub и filter. В частности, см. fromListWith и toList. Используя эти функции, вы можете упростить свою реализацию и повысить производительность одновременно.

Ответ 2

Один из способов улучшить читаемость - попытаться привыкнуть к стандартным функциям. Hoogle является одним из инструментов, который отличает Haskell от остального мира;)

import Data.Char (toLower)
import Data.List (sort, group)
import Control.Arrow ((&&&))

wordCount :: String -> [(String, Int)]
wordCount = map (head &&& length) . group . sort . words . map toLower

EDIT: Объяснение: Итак, вы думаете о нем как о цепочке сопоставлений:

  • (map toLower) :: String -> String уменьшает весь текст, для случая нечувствительность
  • words :: String -> [String] разбивает фрагмент текста на слова
  • sort :: Ord a => [a] -> [a] Сортировка
  • group :: Eq a => [a] -> [[a]] собирает идентификационные элементы в списке, например group [1,1,2,3,3][[1,1],[2],[3,3]]
  • &&& :: (a -> b) -> (a -> c) -> (a -> (b, c)) применяет две функции к одному и тому же фрагменту данных, затем возвращает кортеж результатов. Например: (head &&& length) ["word","word","word"]("word", 3) (фактически &&& является немного более общим, но упрощенное объяснение работает для этого примера)

РЕДАКТИРОВАТЬ: или на самом деле, найдите пакет "multiset" на Hackage.

Ответ 3

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

Относительно функции nub1. Если вы не будете следовать рекомендациям luqui, чтобы полностью удалить параметр, я бы, по крайней мере, удалил круглую скобку вокруг xs в правой части уравнения.

Ответ 4

Добавление типов сигнатур функций действительно помогло бы.