Hello great programmers out there,
I'm doing my first steps in haskell and have a function that confuses me:
import Data.List.Split
getncheck_guesslist = do
    line <- getLine
    let tmp = splitOneOf ",;" line
    map read tmp::[Int]
splitOneOf is in Data.List.Split (i installed it with cabal install split)
splitOneOf :: (Eq a)=> [a]->[a]->[[a]]
From the error I get it that there is some type incorrectness - but don't know how to solve this conflicts as IO is still a mystery to me
I want to read an input of integers separated by commas or semicolons and get a list of integers so:
thank you in advance for thoughts and hints - yours ε/2
When you're writing a function that uses the IO monad, any value you want to return from the function must also be in the IO monad.
This means that, instead of returning a value with type [Int], you have to return something with type IO [Int]. To do this, you use the return function, which "wraps up" the value into IO (it actually works for any monad).
Just change the last line to wrap your value with return, like this:
getncheck_guesslist = do
    line <- getLine
    let tmp = splitOneOf ",;" line
    return (map read tmp :: [Int])
                        The "right way" to do it in Haskell is to separate IO from, well, everything else. The direct translation of your code would be this:
getncheck_guesslist :: IO [Int]
getncheck_guesslist = do line <- getLine               -- get
                         return (check_guesslist line) -- check
check_guesslist :: String -> [Int]
check_guesslist line = let tmp = splitOneOf ",;" line
                       in map read tmp
Notice that getncheck_guesslist is simply an IO action. The function doesn't have input parameters, even though it does require (IO) input from getLine.
Also notice that getncheck_guesslist is a simple modification of the getLine IO action.  Isn't there a combinator that would let me push a function to act on the value inside a monad? Stop. Hoogle time!
I have a function (a -> b). I have a value of the input type, but it's stuck in a monad m a. I want to perform the function inside the monad, so the result will inevitably be stuck in the monad too m b. Putting that all together, we hoogle (a -> b) -> m a -> m b. Lo and behold, fmap is just what we were looking for.
get_guesslist = check_guesslist `fmap` getLine
-- or, taking it a step further
get_guesslist = (map read . splitOneOf ",;") `fmap` getLine :: IO [Int]
As a final note, whenever you code a method with the name like somethingAndSomethingElse, it's usually better coding style to write and invoke something and somethingElse as two separate methods. For the final versions, I just renamed it get_guesslist, since conceptually that's what it does. It gets the guesses as a list of Ints.
As a final final note, I have left off at the point where barsoap started. ;) fmap is the same as <$>.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With