Skip to content

Instantly share code, notes, and snippets.

@jmackie
Last active November 17, 2020 13:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jmackie/8a2e61d848bd0058932bc76c2583bb50 to your computer and use it in GitHub Desktop.
Save jmackie/8a2e61d848bd0058932bc76c2583bb50 to your computer and use it in GitHub Desktop.
Writing haskell scripts with a nix-shell shebang line
:set -fwarn-unused-binds -fwarn-unused-imports
:set -i.
:load Request
#! /usr/bin/env nix-shell
#! nix-shell -p "haskell.packages.ghc802.ghcWithPackages (pkgs: with pkgs; [ aeson HTTP ])"
#! nix-shell --pure
#! nix-shell -i runghc
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
{-| Easy, clean Haskell scripting. Courtesy of Nix.
Need some help from ghcid? Fire up your editor from...
$ nix-shell -p "haskell.packages.ghc802.ghcWithPackages (pkgs: with pkgs; [ ghcid aeson HTTP ])"
Okay cool, but wtf version of these packages am I using?
$ ghc-pkg list
-}
import Data.Aeson ((.:))
import qualified Data.Aeson as Aeson
import qualified Data.ByteString.Lazy.Char8 as ByteString
import qualified Network.HTTP as HTTP
import qualified System.IO as IO
main :: IO.IO ()
main = (decodePosts <$> fetchPosts) >>= \case
Left err -> IO.hPutStrLn IO.stderr err
Right posts -> IO.print (length posts)
fetchPosts :: IO ByteString.ByteString
fetchPosts =
do response <- HTTP.simpleHTTP (HTTP.getRequest url)
HTTP.getResponseBody response <#> ByteString.pack
where
url = "http://jsonplaceholder.typicode.com/posts"
decodePosts :: ByteString.ByteString -> Either String [Post]
decodePosts = Aeson.eitherDecode'
data Post = Post
{ userID :: Int
, postID :: Int
, title :: String
, body :: String
} deriving (Show)
instance Aeson.FromJSON Post where
parseJSON = Aeson.withObject "Post" $ \v -> Post
<$> v .: "userId"
<*> v .: "id"
<*> v .: "title"
<*> v .: "body"
(<#>) = flip fmap
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment