Home > Enterprise >  Create a variable inside a function Haskell
Create a variable inside a function Haskell

Time:09-17

I have two strings; one main string, and another one of two chars (eg. "aa").

I want to see if my main string contains the second string and print its indices in the main string.

I have tried to zip the main string with itself so I can inspect every combination of the letters that comes after each other (eg. "abab" = (a,b) (b,a) (a,b)). I zip these tuples with [1..] to have the correct index where the matching string might start ((a,b) 0). Then I take fst(fst h) to extract the first letter from the tuple and see if it matches the first letter of my secondary string. If it does not find any matches, it should run again on the rest of the main string (xs). I used where to declare variable h as head(locateZip x:xs)

locate (x:xs) (y:ys) = if fst(fst h) == y && snd(fst h) == ys then snd h else locate xs (y:ys)
                 where h = head(locateZip x:xs)
locateZip xs = zip(zip xs(tail xs)) [0..]

snd h is used to print the index of the tuple.

It should return something like this:

locate "aabba" "aa" 
0

locate "bbaab" "aa"
2

I know this might look unusual but I am still new and having trouble understanding the errors I get and what works and what doesn't.

I get an error on h saying:

Couldn't match expected type: ((Char, b2), b3) with actual type: [((b0, b0), b1)]

Is the where statement used correctly for this function?

CodePudding user response:

I've found three problems in your code. Two were syntactical and one is a logical problem. I've tried to change as little as possible.

First of all, in the where statement, you must use () with ":" operator:

where h = head(locateZip (x:xs))

In your code Haskell was inferring a different type for locateZip function.

Second, in the comparison below

snd(fst h) == ys

ys is a list and not a character. This is because ":" operator split a list into the first element and the tail of a list, as is happening in the beginning of the function:

locate (x:xs) (y:ys)

Now, the logical problem. Using where, you are generating a zip list whenever locate function is called. However, whenever locateZip function is called, indexes are regenerated. Then, in your original idea, locate function will output 0 whenever the pair is found.

There's also another problem, since your locate function does not have a guard, in the beginning, to stop recursion. Well, after some changes, the code below seems to work as you expected:

locate [] _ = -1
locate phrase pair = locate_aux phrase pair (locateZip phrase)
locate_aux _ _ [] = -1
locate_aux (x:xs) (y1:y2:ys) h = 
    if (fst (fst (head h)) == y1) && (snd (fst (head h)) == y2) then 
        snd (head h) 
    else
        locate_aux xs (y1:y2:ys) (tail h)
locateZip xs = zip(zip xs(tail xs)) [0..]
  • Related