"type error in conditional expression" in Haskell

My source code is below and works great. I wanted to add an "ind" range check, and in the modified version I added an if statement. When I run it, I get a "type error in conditional expression" and I THINK it is due to an output error [[String]] not IO ()?

Is there any other way to check the range of values ​​stored in ind

and produce an output like "error" / "outofrange"?

source

retrieve :: [Int] -> [[String]] -> [[String]]
retrieve [] dat = [[]]
retrieve ind dat = [exC ind d | d <- dat]

      

modified code

retrieve :: [Int] -> [[String]] -> [[String]]
retrieve [] dat = [[]]
retrieve ind dat = if ind>3
                       then putStrLn "not found"
                       else [exC ind d | d <- dat]

      

thanks,

0


a source to share


5 answers


Replace putStrLn

with error

. This will cause your program to halt completely (unless some higher level catches the exception.)



The problem with what you wrote is that you have declared a pure type and then try to do IO, which is not allowed.

+5


a source


There are two errors in this code.

  • You need to use error

    because it is of type String -> a

    insteadString -> IO ()

  • You apply >

    to [Int]

    and Int

    . Assuming you want to check if the length is ind

    at most 3, you would need to call length

    .


Example:

retrieve :: [Int] -> [[String]] -> [[String]]
retrieve [] dat = [[]]
retrieve ind dat | length ind > 3 = error "not found"
                 | otherwise      = [exC ind d | d <- dat]

      

+6


a source


As described in Ganesh's post, you want to do IO in a pure function , which is not possible.

Ways to Express Your Program (* you will have to use anyway length ind > 3

)

1 Use error

(best way) as shown in other posts

2 Use protective masks ( non exhaustive patterns

-exception)

3 Do IO correctly:

retrieve ind dat = if ind >= 3
                    then do return [exC ind d | d <- dat ] 
                    else do putStrLn "error"; return [[]]

      

retrieve

will be of type

retrieve :: [Int] -> [[String]] -> IO [[String]]

      

4 Use Maybe

to express that the computation might fail.

retrieve :: [Int] -> [[String]] -> Maybe [[String]]
retrieve [] dat = [[]]
retrieve ind dat | length ind > 3 = Nothing
                 | otherwise      = Just [exC ind d | d <- dat]

      

+3


a source


To do this, you can use template protection:

retrieve :: [Int] -> [[String]] -> [[String]]
retrieve [] dat = [[]]
retrieve ind dat | ind <= 3 = [exC ind d | d <- dat]

      

If you leave it that way, you get "Non-Exhaustive Templates in Extract Function". You can also add another custom error case:

retrieve _ _ = error "Out of range"

      

+2


a source


A branch then

has a type IO ()

, a type else

has a type [[String]]

. The types of the two branches are if

different, and there is no way to specify a type for an integer if

that does not cause a type conflict with one of the branches.

+1


a source







All Articles