Search code examples
stringhaskellghci

Insert a string starting at a given index


I am completely new to Haskell. I need to insert a given string at a given index of a string that may already be non-empty.

This is what I have so far. However, after seemingly running with no errors, when I ask what the value of t is ghci just hangs indefinitely.

Haskell:

create = ("",0,0,"","")

addText (m,l,p,_,k) i = 
    let a = take p m
        m = drop p m
        full = a++i++m
    in (full, length full, p + length i, "", k)

Where m is the text to add to, l is the length of m and p is the index to start adding the new string at

Output:

*Main> t = create

*Main> t

("",0,0,"","")

*Main> t = addText t "test"

*Main> t

(hangs)


Solution

  • let m = drop p m
    

    is a circular definition. It doesn't mean "set m to be smaller than what m was before", because remember, it is impossible to modify variables in Haskell. Instead, you ignore the existing m, and define a new variable named m, defined in terms of itself: an evaluation which can never be completed. This may seem like a silly feature, but in other situations it is in fact quite useful to define values in terms of themselves, which is why the language allows it.

    You then make the same mistake again, with

    t = addText t "test"
    

    defining t in terms of itself.

    You can fix both of these errors by using uniquely named variables, e.g.

    r = addText t "test"
    

    at which point you will run into exciting new errors: create's inferred type signature does not match the inferred type signature for addText, because of type defaulting rules. If you specify explicit type signatures, or inline the definition of create, you will finally get what you wanted:

    *Main> addText ("",0,0,"","") "test"
    ("test",4,4,"","")