fork download
  1. data Result t
  2. = Ok t
  3. | Err String
  4. deriving (Show, Eq)
  5.  
  6. instance Functor Result where
  7. fmap f (Ok x) = Ok (f x)
  8. fmap _ (Err msg) = Err msg
  9.  
  10. instance Applicative Result where
  11. pure = Ok
  12. Ok f <*> Ok x = Ok (f x)
  13. Ok f <*> Err msg = Err msg
  14. Err msg <*> _ = Err msg
  15.  
  16. instance Monad Result where
  17. (Ok v) >>= k = k v
  18. (Err msg) >>= k = Err msg
  19. return v = Ok v
  20. fail msg = Err msg
  21.  
  22. data Item = Item {
  23. id :: Int,
  24. name :: Maybe String
  25. } deriving (Show, Eq)
  26.  
  27. getId :: Maybe Int -> Result Int
  28. getId Nothing = Err "No ID provided"
  29. getId (Just id) = Ok id
  30.  
  31. getItem :: Int -> Result Item
  32. getItem id
  33. | id `rem` 2 == 0 = Ok ( Item id Nothing)
  34. | id `rem` 3 == 0 = Ok ( Item id (Just ("item-" ++ show id)))
  35. | otherwise = Err ("Item not found, ID = " ++ show id)
  36.  
  37. getName :: Item -> Result String
  38. getName (Item id Nothing ) = Err ("Item has no name, ID = " ++ show id)
  39. getName (Item _ (Just name)) = Ok name
  40.  
  41. doSomethingClever :: Int -> String -> String
  42. doSomethingClever id name = show id ++ " => " ++ name
  43.  
  44. {-
  45.  
  46. tryToDoSomethingClever :: Maybe Int -> Result String
  47. tryToDoSomethingClever idParam = do
  48. id <- getId idParam
  49. item <- getItem id
  50. name <- getName item
  51. return (doSomethingClever id name)
  52.  
  53. tryToDoSomethingClever :: Maybe Int -> Result String
  54. tryToDoSomethingClever idParam =
  55.   getId idParam >>= (\id ->
  56.   getItem id >>= (\item ->
  57.   getName item >>= (\name ->
  58.   return (doSomethingClever id name))))
  59.  
  60. -}
  61.  
  62. tryToDoSomethingClever :: Maybe Int -> Result String
  63. tryToDoSomethingClever idParam =
  64. case getId idParam of
  65. Err msg -> Err msg
  66. Ok id -> case getItem id of
  67. Err msg -> Err msg
  68. Ok item -> case getName item of
  69. Err msg -> Err msg
  70. Ok name -> Ok (doSomethingClever id name)
  71.  
  72. demoInputs = [Nothing, Just 1, Just 2, Just 3]
  73.  
  74. main = mapM_ (print . tryToDoSomethingClever) demoInputs
  75.  
Success #stdin #stdout 0s 4272KB
stdin
Standard input is empty
stdout
Err "No ID provided"
Err "Item not found, ID = 1"
Err "Item has no name, ID = 2"
Ok "3 => item-3"