1
votes

I have a type problem with this function

type Store = [(String, Float)]
evalParser :: String -> Store -> Float -- Boring function who returns a Float

programme :: Store -> IO()
programme store = do
    putStr "@EvmInteractif:$> "
    instruction <- getLine
    putStrLn (show instruction)

    if (estCommande (instruction) == True) then
        do
            res <- evalParser instruction store
            putStrLn "TODO: execution de la commande"
            programme store

And at the line of res's affectation I have this error :

Couldn't match expected type IO Float' with actual typeFloat' In the return type of a call of `evalParser' In a stmt of a 'do' block: v <- evalParser expr store

Can someone tell me the rigth syntax please ? Thanks

1
Use let res = ... instead of res <- ... - luqui
estCommande (instruction) == True ~ estCommande (instruction) - freestyle
Slightly tongue-in-cheek solution: since res isn't used anywhere, you can just delete the offending line. But only slightly tongue-in-cheek, as there's a lesson here, namely: I suspect you believe that merely calling evalParser will "do something", but it won't. This smells like you have made a bit of a mistake; e.g. perhaps evalParser should be returning an updated store to use in the later recursive call to programme, or perhaps you intended to print the result, or both. Or perhaps you did those in the original but cut them out to make a minimal example, in which case kudos! - Daniel Wagner

1 Answers

2
votes

evalParser is pure, you don't need to use do notation to call it. To shimmy fix it, you could just wrap it in a return to stick it in the IO Monad:

res <- return $ evalParser instruction store

To avoid the wrapping/unwrapping altogether though, just don't treat it as an impure value from the start:

let res = evalParser instruction store