Reputation: 2083
I have an IO action that runs the following pattern three times in a row:
runAction :: IO a -> IO Bool
runAction action = do
result <- action
case result of
Right _ -> return True
_ -> return False
callingFunc :: IO Bool
callingFunc = do
resA <- runAction a
resB <- runAction b
resC <- runAction c
return (resA && resB && resC)
a :: IO (Either ByteString Integer)
b :: IO (Either ByteString ByteString)
c :: IO (Either ByteString Bool)
This works fine, but I'd like to eliminate some redundancy. This doesn't work because of the type of the Right side of Either:
{-# LANGUAGE OverloadedStrings #-}
import Control.Monad
import Data.ByteString.Char8 as BSC
runAction :: Bool -> IO (Either ByteString a) -> IO Bool
runAction prev action = do
result <- action
case result of
Right _ -> return prev
_ -> return False
actA :: IO (Either ByteString Integer)
actA = return (Right 1)
actB :: IO (Either ByteString Bool)
actB = return (Right True)
main :: IO ()
main = do
res <- foldM runAction True [actA, actB]
print res
Resulting error:
Actions.hs:25:38:
Couldn't match type ‘Bool’ with ‘Integer’
Expected type: IO (Either ByteString Integer)
Actual type: IO (Either ByteString Bool)
In the expression: actB
In the third argument of ‘foldM’, namely ‘[actA, actB]’
But I never actually look at the value. I just check if I got Right or not.
Is there any way for me to hide or ignore the type of the Right of Either? Is there a better or more idiomatic way to reduce or abstract this?
EDIT: Sorry, must have pasted an old copy of code. Updated.
Upvotes: 1
Views: 177
Reputation: 54068
Your problem comes from the types of actA
and actB
being in the same list. Lists in Haskell are homogenous, you can't mix elements of different types. actA
and actB
have explicitly different types, there's no possible way for the types to be unified. You can't have the type [Either a1 b1, Either a2 b2]
, this sort of thing just doesn't exist (without a lot of extensions and type system magic, anyway).
Upvotes: 2