Skip to content

Instantly share code, notes, and snippets.

@fogus
Last active December 14, 2015 23:09
Show Gist options
  • Save fogus/5163546 to your computer and use it in GitHub Desktop.
Save fogus/5163546 to your computer and use it in GitHub Desktop.
How do I say this Haskell?
-- THE SEARCH CONTINUES
data GenericThing = SpecificThing Char
| DifferentSpecificThing Double
| AnotherSpecificThing String
| YetAnotherDifferentSpecificThing Integer
foo :: [GenericThing] -> GenericThing
foo [] = return $ AnotherSpecificThing ""
foo [SpecificThing one] = -- do something
foo (SpecificThing c : cs) = -- do something else
foo badThings = -- throw if given any other kind of Thing
-- How can I express
-- - Do something for an array of one SpecificThing
-- - Do something else for an array of many SpecificSomethings
-- - Otherwise throw an error
-- The code above only checks the head of the lists, it does not type check the rest in the many case
--- My answer
data GenericThing = SpecificThing Char
| DifferentSpecificThing Double
| AnotherSpecificThing String
| YetAnotherDifferentSpecificThing Integer
extricate :: ThrowsError Char
extricate (SpecificThing c) = return c
extricate notChar = throwError $ FrobnicateError notChar
foo :: [GenericThing] -> GenericThing
foo [] = return $ AnotherSpecificThing ""
foo [SpecificThing one] = -- do something
foo things = mapM extricate things >>= return . AnotherSpecificThing
@dysinger
Copy link

Q:

-- How can I express
-- - Do something for an array of one SpecificThing
-- - Do something else for an array of many SpecificSomethings
-- - Otherwise throw an error

A:

data GenericThing = SpecificThing Char
                  | DifferentSpecificThing Double
                  | YetAnotherDifferentSpecificThing Integer
                  deriving Show

-- showing the use of exceptions (error)

foo :: [GenericThing] -> GenericThing
foo a@(x:xs)
  | specific x && null xs = oneSpecificThing x
  | all specific a        = lotsOfSpecificThings a
  | otherwise             = error "Not All SpecificThings"
  where specific (SpecificThing _) = True
        specific _                 = False
        oneSpecificThing           = id   -- or other impl
        lotsOfSpecificThings       = head -- or other impl
foo _ = error "Bad Input!?"

-- showing another way to do it by using Either

bar :: [GenericThing] -> Either String GenericThing
bar a@(x:xs)
  | specific x && null xs = Right $ oneSpecificThing x
  | all specific a        = Right $ lotsOfSpecificThings a
  | otherwise             = Left "Not All SpecificThings"
  where specific (SpecificThing _) = True
        specific _                 = False
        oneSpecificThing           = id   -- or other impl
        lotsOfSpecificThings       = head -- or other impl
bar _ = Left "Bad Input!?"

-- showing another way to do it with Maybe

baz :: [GenericThing] -> Maybe GenericThing
baz a@(x:xs)
  | specific x && null xs = Just $ oneSpecificThing x
  | all specific a        = Just $ lotsOfSpecificThings a
  | otherwise             = Nothing
  where specific (SpecificThing _) = True
        specific _                 = False
        oneSpecificThing           = id   -- or other impl
        lotsOfSpecificThings       = head -- or other impl
baz _ = Nothing

-- main so you can try it - use `runhaskell ./Gist.hs`

main :: IO ()
main = do
  putStrLn . show $ foo [SpecificThing 'u']
  putStrLn . show $ bar [SpecificThing 'a', SpecificThing 'b']
  putStrLn . show $ baz [SpecificThing 'a', DifferentSpecificThing 2.0]
  putStrLn . show $ bar [YetAnotherDifferentSpecificThing 5]
  putStrLn . show $ foo [YetAnotherDifferentSpecificThing 5, DifferentSpecificThing 2.0]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment