Bulat Ziganshin bulat.ziganshin at gmail.com
Mon Sep 18 08:06:08 EDT 2006

```Hello Carajillu,

Monday, September 18, 2006, 1:51:34 PM, you wrote:

> Hi, I'm a student and I have to do a program with Haskell. This is the first
> time I use this languaje, and I'm having problems with the indentation. I
> want to check if this function is correct, but when I try to make the GHCi
> interpret it, I get "line 18:parse error (possibly incorrect indentation)"

> The function is:

> -- Replaces a wildcard in a list with the list given as the third argument
> substitute :: Eq a => a -> [a] -> [a] -> [a]
> substitute e l1 l2= [check_elem c | c <- l1] where
>         check_elem::Eq a => a -> [a]
>         check_elem x =
>                 if x == e then return l2

Haskell functions are like mathematical ones - first, you don't need
to use 'return' to denote result - just write it. second, you should
provide results for any possible input values, otherwise function will
just fail on return values for which you don't provided result. 'if'
construct ensures this by forcing to write both 'then' and 'else'
parts. so, your function, probably, should return l2 if comparison
succeeds, and x otherwise:

>         check_elem x =
>                 if x == e then l2 else x

next problem is that x and l2 had different types and type-checking
will not allow you to write this. It's right - you can't construct
list, whose some elements are, for example,

-- i've got a break to rescue a bat that was flied into our house :)

Int and some - [Int]:  [1,[0,0,0],3,4] is impossible

if your need to replace all elements of l1 that are equal to e,
with _several_ list elements, i.e.

substitute 2 [1,2,3,4] [0,0,0] = [1,0,0,0,3,4]

you should use the following technique:

replace all elements of l1 with either l2 or [x] (where x is original
list element). result of such operation:

substitute1 2 [1,2,3,4] [0,0,0] = [[1],[[0,0,0],[3],[4]]

i.e. now all elements are lists, although some have just one element.
then you should use concat operation to transform this list into what
you need:

concat [[1],[[0,0,0],[3],[4]] = [1,0,0,0,3,4]

i think that you are interested to write the complete solution yourself.
just note that there is concatMap function that will allow you to
further simplify the code

> -- Tries to match two lists. If they match, the result consists of the
> sublist
> -- bound to the wildcard in the pattern list.
> (line 18) match :: Eq a => a -> [a] -> [a] -> Maybe [a]
> match _ _ _ = Nothing
> {- TO BE WRITTEN -}

this definition is perfectly ok :)

--
Best regards,
Bulat                            mailto:Bulat.Ziganshin at gmail.com

```