Olian04
Olian04

Reputation: 6872

"do" multiple things in a function

I'm new.

So i got this working:

foo :: String -> String
foo s = do replace "aoa" "a" s

(Typing foo "aoa" returns "a")
But when i add another replace:

foo :: String -> String
foo s = do replace "aoa" "a" s
           replace "uou" "u" s

(Typing foo "aoa" returns "aoa")

Everything breaks and i get this warning:

A do-notation statement discarded a result of type ‘Char’
Suppress this warning by saying ‘_ <- replace "aoa" "a" s’
or by using the flag -fno-warn-unused-do-bind

Since i don't want to suppress the warning, this error message says nothing to me.

What am i missing?

Edit1
Examples:

"aoaaoa" -> "aa"   //Affected
"uouaoa" -> "ua"   //Affected
"aua" -> "aua"     //Not affected

Upvotes: 1

Views: 3329

Answers (2)

hugomg
hugomg

Reputation: 69944

do-notation is for "monad stuff". In this case I would prefer to just chain function calls together.

foo :: String -> String
foo s =
    let s' = replace "aoa" "a" s in
    replace "uou" "u" s'

Since Haskell variables are immutable, we cannot update s with a new value and must instead create a new variable every time. A common idiom is to add a ' to the end of a variable name - its a valid variable name in Haskell.

You could also do it like this:

foo :: String -> String
foo s =
    let s'  = replace "aoa" "a" s  in
    let s'' = replace "uou" "u" s' in
    s''

Upvotes: 2

Chad Gilbert
Chad Gilbert

Reputation: 36375

You don't need to use do notation to achieve a simple string replacement. But since strings are Monads, the compiler is assuming that you meant to use the string as a Monad and giving you an error message with that assumption.

If you want to simply chain together two calls to replace, you could write:

foo s = replace "uou" "u" (replace "aoa" "a" s)

Upvotes: 9

Related Questions