Skip to content

Instantly share code, notes, and snippets.

View snoyberg's full-sized avatar

Michael Snoyman snoyberg

View GitHub Profile
import qualified Control.Concurrent.MVar as IO
import Control.Monad.IO.Control (MonadControlIO, controlIO)
import Control.Exception.Control (mask, onException)
import Control.Monad.IO.Class (liftIO)
modifyMVar :: MonadControlIO m => IO.MVar a -> (a -> m (a, b)) -> m b
modifyMVar m io =
mask $ \restore -> do
a <- liftIO $ IO.takeMVar m
(a',b) <- restore (io a) `onException` liftIO (IO.putMVar m a)
@snoyberg
snoyberg / no-clientsession.hs
Created September 21, 2011 05:25
Demonstrates that clientsession is not used for static routes
{-# LANGUAGE OverloadedStrings, TemplateHaskell, QuasiQuotes,
TypeFamilies, MultiParamTypeClasses #-}
import Yesod.Core
import Yesod.Static
import Network.Wai.Handler.Warp (run)
data NCS = NCS { getStatic :: Static }
instance Yesod NCS where
approot _ = ""
@snoyberg
snoyberg / gist:1258341
Created October 3, 2011 02:59
All HTML character entities
allEntities :: Map.Map T.Text T.Text
allEntities = Map.fromList
[ ("nbsp", "\160")
, ("iexcl", "\161")
, ("cent", "\162")
, ("pound", "\163")
, ("curren", "\164")
, ("yen", "\165")
, ("brvbar", "\166")
, ("sect", "\167")
@snoyberg
snoyberg / Unwrap.hs
Created October 4, 2011 07:28
Unwrap monad stacks within the enumeator package
{-# LANGUAGE RankNTypes #-}
module Data.Enumerator.Unwrap
( unwrapEnumeratee
, unwrapStep
, unwrapIter
, liftStep
) where
import Control.Monad.Trans.Class (MonadTrans)
import Control.Exception (Exception, toException)
@snoyberg
snoyberg / gist:1267589
Created October 6, 2011 14:50
Catch exceptions in an Iteratee
import Control.Exception (Exception, catch)
import Data.Enumerator (Iteratee (..), Step (..))
import Data.ByteString (ByteString)
import Prelude hiding (catch)
catchIter :: Exception e
=> Iteratee ByteString IO a
-> (e -> Iteratee ByteString IO a)
-> Iteratee ByteString IO a
catchIter (Iteratee mstep) f = Iteratee $ do
@snoyberg
snoyberg / randomiv.hs
Created November 26, 2011 19:43
A faster randomIV
import Criterion.Main
import qualified Crypto.Modes as Modes
import qualified Crypto.Classes as Classes
import qualified Crypto.Cipher.AES as A
import qualified Data.IORef as I
import qualified Crypto.Random as R
import System.IO.Unsafe (unsafePerformIO)
import Data.Word (Word8, Word32, Word64)
import qualified System.Random.Mersenne as M
import qualified Data.ByteString as S
@snoyberg
snoyberg / aeson-deepseq-1.2.diff
Created November 30, 2011 06:53
Allow aeson 0.3 to work with deepseq 1.2
diff --git a/Data/Aeson/Types.hs b/Data/Aeson/Types.hs
index 8454bab..290d54f 100644
--- a/Data/Aeson/Types.hs
+++ b/Data/Aeson/Types.hs
@@ -212,13 +212,20 @@ data Value = Object Object
deriving (Eq, Show, Typeable, Data)
instance NFData Value where
- rnf (Object o) = rnf o
+ rnf (Object o) = obj_rnf o
@snoyberg
snoyberg / branch.hs
Created December 29, 2011 08:34
branch in conduits
{-# LANGUAGE NoMonomorphismRestriction #-}
import Data.Conduit
import qualified Data.Conduit.List as CL
branch :: Resource m
=> Sink lIn m lOut
-> Sink rIn m rOut
-> Sink (Either lIn rIn) m (lOut, rOut)
branch (Sink mlsink) (Sink mrsink) = Sink $ do
lsink <- mlsink
@snoyberg
snoyberg / cleanup.hs
Created December 29, 2011 09:53
Yesod module list
import Data.Char
import Data.Maybe
import Data.List
main = do
putStrLn "<table border='1' cellpadding='5'><thead><tr><th></th><th>Repository</th><th>Package</th><th>Module</th></tr></thead><tbody>"
interact $ \s -> unlines $ zipWith row (sort $ mapMaybe tuple $ lines s) [1..]
putStrLn "</tbody></table>"
tuple x =
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses, ScopedTypeVariables #-}
module Database.CouchDB.Conduit.Test.Basic (tests) where
import Test.Framework (testGroup, Test)