how can this code be less?

I wrote this code and Can it be less? [2,4,5]list is sub list of [3,7,2,4,5,9] list and return True but not of[3,7,4,2,5,9] list ; return False sublist :: Eq a => [a] -> [a] -> Bool sublist [] _ = True sublist (_:_) [] = False sublist (x:xs) (y:ys) | x == y = if isEqual (x:xs) (y:ys) == False then sublist (x:xs) ys else True | otherwise = sublist (x:xs) ys isEqual :: Eq a => [a] -> [a] -> Bool isEqual [] _ = True isEqual (_:_) [] = False isEqual (x:xs) (y:ys) | x==y = isEqual xs ys | otherwise = False ____________________________________________________________________________________ Be a better friend, newshound, and know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ

cetin tozkoparan wrote:
I wrote this code and Can it be less? [2,4,5] list is sub list of [3,7,*2,4,5*,9] list and return True but not of [3,7,*4,2,5*,9] list ; return False
sublist :: Eq a => [a] -> [a] -> Bool sublist [] _ = True sublist (_:_) [] = False sublist (x:xs) (y:ys) | x == y = if isEqual (x:xs) (y:ys) == False then sublist (x:xs) ys else True | otherwise = sublist (x:xs) ys
isEqual :: Eq a => [a] -> [a] -> Bool isEqual [] _ = True isEqual (_:_) [] = False isEqual (x:xs) (y:ys) | x==y = isEqual xs ys | otherwise = False
One way is to use existing library functions as Henning suggested (but maybe you missed it because he mischievously changed the subject!) Henning Thielemann wrote:
try 'List.tails' and 'List.isPrefixOf'
You should be able to define sublist using only some combination of the following (and one pair of parentheses) in one line of code! import List(isPrefixOf,tails) (.) :: (b -> c) -> (a -> b) -> a -> c any :: (a -> Bool) -> [a] -> Bool tails :: [a] -> [[a]] isPrefixOf :: (Eq a) => [a] -> [a] -> Bool

I think you're looking for Data.List.isInfixOf.
Alex
On Thu, Apr 24, 2008 at 7:40 PM, Dan Weston
cetin tozkoparan wrote:
I wrote this code and Can it be less? [2,4,5] list is sub list of [3,7,*2,4,5*,9] list and return True but not of [3,7,*4,2,5*,9] list ; return False
sublist :: Eq a => [a] -> [a] -> Bool sublist [] _ = True sublist (_:_) [] = False sublist (x:xs) (y:ys) | x == y = if isEqual (x:xs) (y:ys) == False then sublist (x:xs) ys else True | otherwise = sublist (x:xs) ys
isEqual :: Eq a => [a] -> [a] -> Bool isEqual [] _ = True isEqual (_:_) [] = False isEqual (x:xs) (y:ys) | x==y = isEqual xs ys | otherwise = False
One way is to use existing library functions as Henning suggested (but maybe you missed it because he mischievously changed the subject!)
Henning Thielemann wrote:
try 'List.tails' and 'List.isPrefixOf'
You should be able to define sublist using only some combination of the following (and one pair of parentheses) in one line of code!
import List(isPrefixOf,tails)
(.) :: (b -> c) -> (a -> b) -> a -> c any :: (a -> Bool) -> [a] -> Bool tails :: [a] -> [[a]] isPrefixOf :: (Eq a) => [a] -> [a] -> Bool _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

cetin tozkoparan
sublist :: Eq a => [a] -> [a] -> Bool sublist [] _ = True sublist (_:_) [] = False
This can be simplified a bit, I think (Reformatted to one line):
sublist (x:xs) (y:ys) | x == y = if isEqual (x:xs) (y:ys) == False then sublist (x:xs) ys else True
I don't like the "== False" for boolean expressions, so I'd write: sublist (x:xs) (y:ys) | x == y = if not (isEqual (x:xs) (y:ys)) then sublist (x:xs) ys else True Or, swithing then and else clauses: sublist (x:xs) (y:ys) | x == y = if isEqual (x:xs) (y:ys) then True else sublist (x:xs) ys If you look at the following clause:
| otherwise = sublist (x:xs) ys
you'll notice that it is the same as the "else" clause. We can therefore write: sublist (x:xs) (y:ys) | x == y && isEqual (x:xs) (y:ys) = True | otherwise = sublist (x:xs) ys isEqual will re-test x==y, so this is redundant: sublist (x:xs) (y:ys) | isEqual (x:xs) (y:ys) = True | otherwise = sublist (x:xs) ys The pattern guard is a bit gratuitious, why not write: sublist (x:xs) (y:ys) = isEqual (x:xs) (y:ys) || sublist (x:xs) ys Which is how you'd define the problem: a list xs is a sublist of ys if they have equal prefixes, or if xs is a sublist of the tail of ys.
isEqual :: Eq a => [a] -> [a] -> Bool
Slightly misleading name, since it checks a prefix, not complete equality.
isEqual [] _ = True isEqual (_:_) [] = False isEqual (x:xs) (y:ys) | x==y = isEqual xs ys | otherwise = False
Similar to the above, you could write: isEqual (x:xs) (y:ys) = x == y && isEqual xs ys "lists (x:xs) and (y:ys) 'isEqual' if x == y and xs 'isEqual' ys" As pointed out, you could (and should) write this using a couple of Prelude functions. Oh, any errors in the code are left as excercises for the reader (in other words, I didn't test this code at all, but don't want to be perceived as lazy.) -k -- If I haven't seen further, it is by standing in the footprints of giants

You may want to study the code form Data.List first: isInfixOf :: (Eq a) => [a] -> [a] -> Bool isInfixOf needle haystack = any (isPrefixOf needle) (tails haystack) cetin tozkoparan wrote:
I wrote this code and Can it be less? [2,4,5] list is sub list of [3,7,*2,4,5*,9] list and return True but not of [3,7,*4,2,5*,9] list ; return False
sublist :: Eq a => [a] -> [a] -> Bool sublist [] _ = True sublist (_:_) [] = False sublist (x:xs) (y:ys) | x == y = if isEqual (x:xs) (y:ys) == False then sublist (x:xs) ys else True | otherwise = sublist (x:xs) ys
isEqual :: Eq a => [a] -> [a] -> Bool isEqual [] _ = True isEqual (_:_) [] = False isEqual (x:xs) (y:ys) | x==y = isEqual xs ys | otherwise = False
isEqual is not needed, because "Eq" provides "==" over lists, too. HTH Christian

Christian Maeder wrote:
isEqual :: Eq a => [a] -> [a] -> Bool isEqual [] _ = True isEqual (_:_) [] = False isEqual (x:xs) (y:ys) | x==y = isEqual xs ys | otherwise = False
isEqual is not needed, because "Eq" provides "==" over lists, too.
Ah, isEqual isn't "==", but isPrefixOf. C.
participants (5)
-
Alexander Dunlap
-
cetin tozkoparan
-
Christian Maeder
-
Dan Weston
-
Ketil Malde