[Haskell-beginners] Indentation of local functions

Miguel Pignatelli miguel.pignatelli at uv.es
Mon Feb 16 18:24:23 EST 2009


Nice!
Thanks a lot for the explanation. (and to the others that have replied!)

M;


El 16/02/2009, a las 17:05, Daniel Fischer escribió:

> Am Montag, 16. Februar 2009 16:32 schrieb Miguel Pignatelli:
>> Hi all,
>>
>> This is my first post in this forum, I'm pretty new to Haskell
>> (although I have some previous experience in functional programming
>> with OCaml).
>>
>> I'm trying to write the typical function that determines if a list is
>> a palindrome.
>> The typical answer would be something like:
>>
>> isPalindrome xs = xs == (reverse xs)
>>
>> But I find this pretty inefficient (duplication of the list and  
>> double
>> of needed comparisons).
>> So I tried my own version using just indexes:
>>
>> isPalindrome xs =
>>   	isPalindrome' 0 (length xs)
>>   	where isPalindrome' i j =
>>             if i == j   -- line 43
>>             then True
>>             else
>>             	if (xs !! i) == (xs !! (j-1))
>>             	then isPalindrome' (i+1) (j-1)
>>             	else False
>>
>> But, when trying to load this in ghci it throws the following error:
>>
>> xxx.hs:43:12: parse error (possibly incorrect indentation)
>> Failed, modules loaded: none.
>> (Line 43 is marked in the code)
>>
>> I seems that the definition of isPalindrome' must be in one line. So,
>> this works as expected:
>>
>> isPalindrome xs =
>>   	isPalindrome' 0 (length xs)
>>   	  where isPalindrome' i j = if i == j then True else if (xs !! i)
>> == (xs !! (j-1)) then isPalindrome' (i+1) (j-1) else False
>>
>> Is there any way to make the local definition of isPalindrome' more
>> readable?
>>
>
> Yes, it would be horrible to look at Haskell code if there weren't.
> The problem is that originally, the code for isPalindrome' was  
> indented less
> than the function name. Specifically, the first relevant token (i.e.  
> not
> whitespace or comments) after the keywords do, let, where, case ... of
> opens up a new scope, which lasts until something is indented less  
> or equally
> far.
> To not suffer from e-mailing programmes behaviour regarding leading  
> spaces on
> a line, I replace those with '°', then a more readable formatting of  
> your
> code would be
>
> isPalindrome xs = isPalindrome' 0 (length xs)
> °°°where
> °°°°°°isPalindrome' i j
> °°°°°°°°°| j <= i 	= True
> °°°°°°°°°| xs !! i /= xs !! (j-1)	= False
> °°°°°°°°°| otherwise = isPalindrome (i+1) (j-1)
>
> I have replaced your nested ifs by guards (increases readability,  
> IMO) and
> corrected the stopping condition so that it also works on words of odd
> length.
>
> However, note that Haskell lists aren't arrays, but singly linked  
> lists, so to
> find xs !! k, all the first (k+1) cells of the list must be visited,  
> making
> your algorithm less efficient than the naive one, since you must visit
> O((length xs)^2) cells.
>
>> Any help in understanding this would be appreciated
>>
>> Thanks in advance,
>>
>> M;
>
> Cheers,
> Daniel
>
>



More information about the Beginners mailing list