I'm struggling to find a way to return only the first half of a string.
I have a code that checks if a string is a palindrome, and if it is, I want to return only the first half using Just
. If it is not a palindrome it should just return Nothing
Ex. halfPalindrome "boy"
should return Nothing
and halfPalindrome "abba"
should return Just "ab"
.
I've tried different things, but it seems as though I need a helper function.
halfPalindrome :: String -> Maybe String
halfPalindrome x =
if x == reverse x
then
Just half
else Nothing
half :: [a] -> ([a], [a])
half xs = (take 1 xs, drop 1 xs)
where 1 = div (length xs) 2
I'm not sure how to implement/use my helper function correctly
EDIT
Final code works. Thank you guys :)
halfPalindrome :: String -> Maybe String
halfPalindrome x
| x == reverse x = let (a, _) = half x in Just a
| otherwise = Nothing
first_half :: [a] -> [a]
first_half = (\xs -> case xs of
[] -> []
xs -> take ((length xs) `div` 2 ) xs)
second_half :: [a] -> [a]
second_half = (\xs -> case xs of
[] -> []
xs -> drop ((length xs) `div` 2 ) xs)
half :: [a] -> ([a],[a])
half = (\xs -> case xs of
[] -> ([],[])
xs -> (first_half xs, second_half xs))
CodePudding user response:
half
is a function, you thus should call this with x
and return the first part, so:
halfPalindrome :: String -> Maybe String
halfPalindrome x
| x == reverse x = let (a, _) = half x in Just a
| otherwise = Nothing
It is however not necessary to determine the length
of the list to return the half. You can work with two "iterators" that "walk" over the same list, but where the second one takes "hops" of two, and thus if that one reaches the end of the list, the first one is located in the middle of the String
.