0

My function takes 2 strings and determines if the first string is a substring of the second input string. For instance:

isSubb "abc" "abcmhk" -- True
isSubb "abc" "uyabcmhk" -- True
isSubb "abc" "okaibcmhk" -- False
isSubb "abc" "amnabkaaabcmhk" -- gives True

So far I have:

isSubb :: [Char] -> [Char] -> Bool
isSubb sub str = auxx sub sub str

auxx :: [Char] -> [Char] -> [Char] -> Bool
auxx safe (s:ub) (st:r)
| s:ub == []    = True
| st:r == []  = False
| s == st   = auxx safe ub r
| otherwise  = auxx safe safe r

But its giving me a non-exhaustive error on the auxx function.

Any help is greatly appreciated! Thank you!

2
  • A bit nitpicking: you are looking for substrings (or sublists), not for subsets. Because "abc" is surely a subset of "axbycz", ins't it? Commented Nov 18, 2013 at 0:41
  • Good point. I will edit Commented Nov 27, 2015 at 3:32

3 Answers 3

4

In Data.List there is the isInfixOF function.

isInfixOf :: Eq a => [a] -> [a] -> Bool

The isInfixOf function takes two lists and returns True iff the first list is contained, wholly and intact, anywhere within the second.

Prelude Data.List> isInfixOf "abc" "abcmhk"
True
Prelude Data.List> isInfixOf "abc" "uyabcmhk"
True
Prelude Data.List> isInfixOf "abc" "okaibcmhk"
False
Prelude Data.List> isInfixOf "abc" "amnabkaaabcmhk"
True

You could write your function like

import Data.List (isInfixOf)

isSubb :: [Char] -> [Char] -> Bool
isSubb sub str = isInfixOf sub str
Sign up to request clarification or add additional context in comments.

Comments

3

Your auxx function needs to take into account the cases where the second or the third parameters are [] (because you are getting there).

The s:ub == [] and st:r == [] will never be True since pattern matching happens before guard evaluation.

A sane equivalent of you function would be

auxx safe sub str
  | sub == [] = True
  | str == [] = False
  | head sub == head str = auxx safe ub r
  | otherwise = auxx safe safe r

Though the above is not efficient since it can be improved by pattern matching.

auxx _ [] _ = True
auxx _ _ [] = False
auxx safe (s:ub) (st:r)
  | s == st = auxx safe ub r
  | otherwise = auxx safe safe r

2 Comments

Thank you! This worked beautifully! i was trying to figure out something like that and didnt know you could use _
_ stands for anything, you can place there a variable name and it will be pattern matched and bound but using _ is desirable because no pattern match and variable binding occurs - it is simply discarded.
-1

Your definition is not correct!

 | s == st   = auxx safe ub r

gives problems. Look, determining whether "abc" is in "afkjskgsbc" is not the same as determining whether "bc" is in "fkjskgsbc" . So you need to consider that the first letter may or may not be a part of the string you're looking for.

3 Comments

This doesn't solve his error message. And, have you looked at his examples?
You're right, my answer is not helpful and he already has a right test case to check for. Sorry!
Also what you say is the problem in your answer is not a problem. Look at the otherwise branch

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.