Reputation: 415
As part of a larger project written in Haskell, I am working on a small utility library to encapsulate common paradigms I use throughout my code. One function (or two functions, rather) that I was working on are fromLeft :: Either a b -> a
and fromRight :: Either a b -> b
, which are partial functions that are undefined (error
to be exact) on antichiral constructors:
fromLeft :: Either a b -> a
fromLeft x = case x of
(Left x) -> x
(Right y) -> error "fromLeft: (Right _)"
fromRight :: Either a b -> b
fromRight x = case x of
(Right x) -> x
(Left y) -> error "fromRight: (Left _)"
In any case, I wanted to extend these functions if possible so that, if the y
in the second pattern match for each function were of a type that were show
able, it would be printed instead of "_"
. However, there is no obvious way to go about that without putting a constraint in the signature, which would make these functions lose their generality.
Is there any extension or module voodoo that can selectively perform typeclass functions for instances of those typeclasses and return a general result for other types? More specifically, is there any way in Haskell to write a program that simulates the invalid function
\x -> if (showable x) then show x else "_"
Upvotes: 2
Views: 158
Reputation: 89093
How about this:
fromRightWith :: (a -> String) -> Either a b -> b
fromRightWith show (Left a) = error $ "fromRight: (Left " ++ show a ++ ")"
fromRightWith _ (Right b) = b
fromRight :: Either a b -> b
fromRight = fromRightWith $ const "_"
fromRight' :: Show a => Either a b -> b
fromRight' = fromRightWith show
Then if, in your code, you know that a
is an instance of Show
, use fromRight'
. If not, use fromRight
:
instance Show MyError where
show = -- ..
trySomething :: IO (Either MyError Value)
trySomething = --- ..
main = do
value <- fromRight' <$> trySomething
-- ..
Upvotes: 4