3

I currently have a function with definition:

f :: [Int] -> Int -> [[Int]]

And have two variables of type IO [Int] and IO Int. I want to pass these variables to this function f. I am able to do this when it is just one variable being passed to the function, but when it is 2 I can't get it to work.

1
  • 1
    A value in a variable of type IO Int is a thing you can do to get an Int. For example "let the user type in a number" is a value of type IO Int. You cannot calculate "let the user type in a number" + "pick a random number". You have to let the user type in a number, then pick a random number, then calculate the first number + the second number. Commented Feb 20, 2020 at 15:06

3 Answers 3

12

You can write a do block:

f' :: IO [[Int]]
f' = do
    x <- val1
    y <- val2
    return (f x y)

with val1 :: IO [Int] and val2 :: IO Int the values you want to pass as parameters.

or in an applicative style:

f' :: IO [[Int]]
f' = f <$> val1 <*> val2

or we can make use of liftA2 :: (a -> b -> c) -> f a -> f b -> f c:

f' :: IO [[Int]]
f' = liftA2 f val1 val2
Sign up to request clarification or add additional context in comments.

Comments

7

You should use <- in do notation and run the function on the unwrapped values.

-- Implementations left out
xsFn :: IO [Int]
xFn :: IO Int

main = do
  xs <- xsFn
  x <- xFn
  -- We've unwrapped the values, so now xs :: [Int] and x :: Int

  let result = f xs x -- result :: [[Int]]
  -- do something with result
  return ()

Comments

2

IO has an Applicative instance, so you can use liftA2:

> f = undefined :: [Int] -> Int -> [[Int]]
> import Control.Applicative
> :t liftA2 f
liftA2 f :: Applicative f => f [Int] -> f Int -> f [[Int]]

With the TypeApplications extension, you can see it more clearly.

> :set -XTypeApplications
> :t liftA2 @IO f
liftA2 @IO f :: IO [Int] -> IO Int -> IO [[Int]]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.