Created
June 4, 2014 18:02
-
-
Save pbrisbin/bca300b913bcb0f1b533 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Within an implementation of the TODO app from LYAH, there was something like | |
-- this... | |
data Todo = Todo | |
newtype Add = Add (Either String Todo) | |
newtype Remove = Remove (Either String ()) | |
newtype Complete = Complete (Either String Todo) | |
class Respond a where | |
-- or something, not important | |
respond a :: a -> IO () | |
instance Respond Add where | |
respond (Add (Right _ t) = putStrLn $ "Added " ++ show t | |
respond (Add (Left e _) = error e | |
instance Respond Remove | |
respond (Add (Right _ ()) = putStrLn "Todo removed!" | |
respond (Add (Left e _) = error e | |
instance Respond Complete | |
respond (Add (Right _ t) = putStrLn $ "Completed " ++ show t | |
respond (Add (Left e _) = error e | |
-- My suggestion: | |
data Action = Add Todo | Remove | Complete Todo | |
type Response = Either String Action | |
respond :: Response -> IO () | |
respond (Right (Add t)) = putStrLn $ "Added " ++ show t | |
respond (Right Remove) = putStrLn $ "Todo removed!" | |
respond (Right (Complete t)) = putStrLn $ "Completed " ++ show t | |
respond (Left e) = error e | |
-- I feel this kind of over-engineering happens to Rubyists specifically, | |
-- because they don't realize Sum types are available, since they're lacking in | |
-- Ruby (and most languages). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I agree pretty much entirely with your sentiment. I think that the difference really comes down to what type of application you're writing. I think it's unlikely when writing a non-library application that you will have a group of values that are similar enough to fit in a type class, but desperate enough that they can't be constructors of a single (sum) type.
This is regardless of scale. For non-library applications, you don't have the issue of defining behavior for types you a) don't know about yet and b) won't be adding yourself in the future. That is when I would for type classes.
Going with a simpler sum type and using pattern exhaustive-ness warnings to ensure correctness when adding new constructors is the way to go 99% of the time (huge, IMO disclaimer here).