Skip to content

Instantly share code, notes, and snippets.

@chpatrick
Created January 1, 2014 18:28
Show Gist options
  • Save chpatrick/8210222 to your computer and use it in GitHub Desktop.
Save chpatrick/8210222 to your computer and use it in GitHub Desktop.
Haskell "Methods" - computations that can either take the "object" they operate on as a parameter, or from the ReaderT monad. Useful when the user wants to perform multiple monadic operations on an immutable value. The downside is that it complicates the types of the functions themselves.
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, FunctionalDependencies #-}
import Control.Monad.Reader
class Method o m a f | f -> o m a where
on :: (o -> m a) -> f
instance Method o m a (o -> m a) where
on = id
instance Method o m a (ReaderT o m a) where
on = ReaderT
(.>) :: o -> ReaderT o m a -> m a
(.>) = flip runReaderT
infixr 1 .>
-- EXAMPLE
type Interface = String
bringUp :: Method Interface IO () f => f
bringUp = on $ \iface -> putStrLn ("bringing up " ++ iface)
setMTU :: Method Interface IO () f => Int -> f
setMTU mtu = on $ \iface -> putStrLn ("setting " ++ iface ++ " MTU to " ++ show mtu)
main :: IO ()
main = do
let iface = "eth0"
bringUp iface -- function style
iface .> do -- reader style
setMTU 42
bringUp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment