2013-10-14 4 views
0

Я хочу создать функцию в haskell, которая возвращает количество раз, когда одно слово является префиксом списка слов. Например: для слова «идти» и списка слов «туз», «идти», «уходить», «гольф»] он должен вернуться 3. Что у меня есть до сих пор:как я могу считать префиксы в haskell?

numberOfPrefixes _ [] = error ("Empty list of strings") 

numberOfPrefixes [] _ = error ("No word") 

numberOfPrefixes (x:xs) (y:ys) 

         | isPrefixOf (x:xs) y = 1 + numberOfPrefixes(x:xs) ys 

         | otherwise = 0 

Но это работает только в том случае, если первый элемент списка слов на самом деле является префиксом. Если первый элемент не является префиксом, все это разваливается. Любая помощь делает это правильно?

isPrefixOf :: (Eq a) => [a] -> [a] -> Bool 
isPrefixOf [] _ = True 
isPrefixOf _ [] = False 
isPrefixOf (x:xs) (y:ys) = x == y && isPrefixOf xs ys 
+0

Привет, я знаю, что вы новичок в SO, но если у вас есть вопрос по моему ответу, отправьте его как комментарий к моему ответу, чтобы я его увидел :) Во-вторых, исправьте вы отступы и измените 'y: ys' на просто' y' в чеке, и он отлично работает – jozefg

+0

Итак, у меня есть еще один вопрос. Любая помощь ? И спасибо за ваш совет, было очень полезно –

+0

Опубликовать это как отдельный вопрос, и я буду рад. – jozefg

ответ

3

Вот как я пишу это

(.:) :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c 
(.:) = (.) . (.) -- A common utility definition 
infixr 9 .: 

prefixCount :: Eq a => [a] -> [[a]] -> Integer 
prefixCount = length .: filter . isPrefixOf 

Или писать это pointfully

prefixCount l ls = length $ filter (isPrefixOf l) ls 

Если вы действительно хотите, чтобы написать это рекурсивно

prefixCount l [] = 0 
prefixCount x (l:ls) | <is prefix?> = 1 + prefixCount x ls 
         | otherwise = prefixCount x ls 

и просто заполнить в <is prefix?> с проверкой, является ли x префиксом l

+0

Можете ли вы объяснить рекурсивное решение? Потому что мне трудно понять это. Можно ли сделать немного более простым? –

+0

@ user2878641 Пустой список содержит 0 элементов с правым префиксом. В противном случае, получите первый элемент, добавьте 1 к остальной части счета остальной части списка. В противном случае добавьте 0 к счету остальной части списка – jozefg

+0

Я хочу использовать эту функцию, которую я создал ранее, чтобы написать эту: isPrefixOf :: (Eq a) => [a] -> [a] -> Bool isPrefixOf [] _ ​​= True isPrefixOf _ [] = False isPrefixOF (x: xs) (y: ys) = x == y && isPrefixOf xs ys –

Смежные вопросы