archaephyrryx
archaephyrryx

Reputation: 415

Haskell: safe 'show'

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 showable, 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

Answers (1)

rampion
rampion

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

Related Questions