Skip to content

Instantly share code, notes, and snippets.

@err0r500
Created August 31, 2018 12:27
Show Gist options
  • Save err0r500/19444174ec5112753ce83d2fd40ca1e9 to your computer and use it in GitHub Desktop.
Save err0r500/19444174ec5112753ce83d2fd40ca1e9 to your computer and use it in GitHub Desktop.
Haskell monadic typeclass
module Main where
import Control.Monad.Identity
-- boostrap the conditions leading to 2 different implementations of the same business logic
main :: IO ()
main = do
-- use a monad instance as 1st parameter in order to choose the implementation
expectedCalledWithMaybeInstance <- putStrLn $ getFirstName Nothing "heyhey"
expectedCalledWithIOInstance <- putStrLn $ getFirstName (Identity 0) "hoho"
putStrLn "done"
class UserGetter a where
getUserByName :: a -> String -> Either String String
instance UserGetter (Identity a) where
getUserByName _ str = Left $ "userFirstName " ++ str
instance UserGetter (Maybe a) where
getUserByName _ str = Right $ "otherUserFirstName " ++ str
-- business logic without any knowledge of the underlying implementation
getFirstName :: (UserGetter m) => m -> String -> String
getFirstName ctx name = do
let firstName = getUserByName ctx name
case firstName of
Left str -> "called from Identity " ++ str
Right str -> "called from Maybe " ++ str
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment