While I can apply a function two times and bind result in a tuple:
let foo :: Num a => a -> a
foo x = x + 1
let (x,y) = (foo 10, foo 20)
This can't be done (ar at least I don't know how to do it properly) within a do
block:
let bar :: Num a => a -> IO a
bar x = do
let y = x + 1
return y
let test :: Num a => IO a
test = do
(x,y) <- (bar 10, bar 20)
return y
I got the following error when typing it GHCI REPL:
:29:15:
Couldn't match expected type ‘IO a1’ with actual type ‘(t0, a)’
Relevant bindings include
test :: IO a (bound at :28:5)
In the pattern: (x, y)
In a stmt of a 'do' block: (x, y) <- (bar 10, bar 20)
In the expression:
do { (x, y) <- (bar 10, bar 20);
return y }
:29:24:
Couldn't match type ‘(,) (IO a0)’ with ‘IO’
Expected type: IO (IO a1)
Actual type: (IO a0, IO a1)
In a stmt of a 'do' block: (x, y) <- (bar 10, bar 20)
In the expression:
do { (x, y) <- (bar 10, bar 20);
return y }
In an equation for ‘test’:
test
= do { (x, y) <- (bar 10, bar 20);
return y }
I can obviously solve it with a more verbose:
let test' :: Num a => IO a
test' = do
x <- bar 10
y <- bar 20
return y
Is there a correct way to express test
without making it like test'
?