Skip to content

Instantly share code, notes, and snippets.

@bananu7
Created February 19, 2015 17:43
Show Gist options
  • Save bananu7/0edf036c61435532d67a to your computer and use it in GitHub Desktop.
Save bananu7/0edf036c61435532d67a to your computer and use it in GitHub Desktop.
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
import Control.Monad.Reader
class Iso a b where
isoFrom :: a -> b
isoTo :: b -> a
instance Iso a a where
isoFrom = id
isoTo = id
-- real-life sample
type MyState = Int
type Callback = MyState -> MyState
testCallback :: MyState -> Callback -> MyState
testCallback myState cb = cb myState
testCallbackGeneric :: Iso Callback a => MyState -> a -> MyState
testCallbackGeneric myState cb = (isoTo cb) myState
callbackFunction :: Callback
callbackFunction s = s + 10
-- we need a proof of isomorphism
{-
instance Iso Callback (Reader MyState MyState) where
isoFrom cb = reader cb
isoTo m = runReader m
-}
-- a more generic version, proving my point
instance Iso (a -> b) (Reader a b) where
isoFrom f = reader f
isoTo m = runReader m
callbackMonad :: Reader MyState MyState
callbackMonad = do
x <- ask
return $ x - 10
main :: IO ()
main = do
let myState = 42
let myStateA = testCallback myState callbackFunction
-- let myStateB = testCallback myState callbackMonad -- won't work, obviously
let myStateC = testCallbackGeneric myState callbackFunction
let myStateD = testCallbackGeneric myState callbackMonad
print myStateA
--print myStateB
print myStateC
print myStateD
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment