1{-# LANGUAGE DataKinds #-}
2{-# LANGUAGE DeriveGeneric #-}
3{-# LANGUAGE OverloadedStrings #-}
4{-# LANGUAGE TypeOperators #-}
5{-# OPTIONS_GHC -fno-warn-unused-imports #-}
6import Control.Applicative
8import Control.Monad.IO.Class
9import Control.Monad.Trans.Except
13import Data.Text (Text)
15import Network.HTTP.Client (Manager, defaultManagerSettings,
17import System.IO.Unsafe (unsafePerformIO)
21import qualified Data.Text as T
22import qualified Data.Text.IO as T
25 "users" :> Get '[JSON] [UserSummary]
26 :<|> "user" :> Capture "username" Username :> Get '[JSON] UserDetailed
27 :<|> "packages" :> Get '[JSON] [Package]
31data UserSummary = UserSummary
32 { summaryUsername :: Username
33 , summaryUserid :: Int
36instance FromJSON UserSummary where
37 parseJSON (Object o) =
38 UserSummary <$> o .: "username"
45data UserDetailed = UserDetailed
46 { username :: Username
49 } deriving (Eq, Show, Generic)
51instance FromJSON UserDetailed
53newtype Package = Package { packageName :: Text }
54 deriving (Eq, Show, Generic)
56instance FromJSON Package
58hackageAPI :: Proxy HackageAPI
62{-# NOINLINE manager #-}
64manager = unsafePerformIO $ newManager defaultManagerSettings
66getUsers :: ExceptT ServantError IO [UserSummary]
67getUser :: Username -> ExceptT ServantError IO UserDetailed
68getPackages :: ExceptT ServantError IO [Package]
69getUsers :<|> getUser :<|> getPackages =
70 client hackageAPI (BaseUrl Http "hackage.haskell.org" 80 "") manager
73main = print =<< uselessNumbers
75uselessNumbers :: IO (Either ServantError ())
76uselessNumbers = runExceptT $ do
78 liftIO . putStrLn $ show (length users) ++ " users"
81 putStrLn "Enter a valid hackage username"
83 userDetailed <- getUser user
84 liftIO . T.putStrLn $ user <> " maintains " <> T.pack (show (length $ groups userDetailed)) <> " packages"
86 packages <- getPackages
87 let monadPackages = filter (isMonadPackage . packageName) packages
88 liftIO . putStrLn $ show (length monadPackages) ++ " monad packages"
90 where isMonadPackage = T.isInfixOf "monad"
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list