title | author |
---|---|
Contravariant and Trace |
Denis Shevchenko |
f a
What is it?
Maybe Int
Maybe Int
is a producer.
Maybe Int
is a producer: mapping produces some Int
value in Maybe
context.
> fmap (* 10) $ Just 3
Just 30
contramap :: (a -> b) -> f b -> f a
contramap :: (a -> b) -> f b -> f a
fmap :: (a -> b) -> f a -> f b
fmap :: (a -> b) -> f a -> f b
We can apply a -> b
to f a
to produce f b
.
contramap :: (a -> b) -> f b -> f a
But we cannot apply a -> b
to f b
to produce f a
. :-(
contramap :: (a -> b) -> f b -> f a
But we cannot apply a -> b
to f b
to produce f a
. :-(
This is because f b
is not a producer!
newtype MyStringifier a = MyStringifier { runStringifier :: a -> String }
intStringifier :: MyStringifier Int
intStringifier = MyStringifier show
What is MyStringifier Int
?
MyStringifier Int
is a consumer!
MyStringifier Int
is a consumer: it consumes Int
value and stringifies it.
instance Contravariant MyStringifier where
contramap f (MyStringifier stringifier) = MyStringifier (stringifier . f)
stringifier . f
newtype MySuperNumber = MySuperNumber Int
newtype MySuperNumber = MySuperNumber Int
someFunc :: MySuperNumber -> Int
someFunc (MySuperNumber i) = i * 10
newtype MySuperNumber = MySuperNumber Int
someFunc :: MySuperNumber -> Int
someFunc (MySuperNumber i) = i * 10
intStringifier :: MyStringifier Int
intStringifier = MyStringifier show
newtype MySuperNumber = MySuperNumber Int
someFunc :: MySuperNumber -> Int
someFunc (MySuperNumber i) = i * 10
intStringifier :: MyStringifier Int
intStringifier = MyStringifier show
main :: IO ()
main = do
let superNumberStringifier = contramap someFunc intStringifier
result = runStringifier superNumberStringifier $ MySuperNumber 12
putStrLn result
contramap someFunc intStringifier
instance Contravariant MyStringifier where
contramap f (MyStringifier stringifier) = MyStringifier (stringifier . f)
contramap someFunc intStringifier = MyStringifier (runStringifier intStringifier . someFunc)
contramap someFunc intStringifier = MyStringifier (runStringifier intStringifier . someFunc)
-----------------------------
Int -> String
contramap someFunc intStringifier = MyStringifier (runStringifier intStringifier . someFunc)
----------------------------- --------
Int -> String MySuperNumber -> Int
contramap someFunc intStringifier = MyStringifier (runStringifier intStringifier . someFunc)
----------------------------------------
MySuperNumber -> String
someFunc :: MySuperNumber -> Int
someFunc (MySuperNumber i) = i * 10
main :: IO ()
main = do
let superNumberStringifier = contramap someFunc intStringifier
result = runStringifier superNumberStringifier $ MySuperNumber 12
putStrLn result
intStringifier :: MyStringifier Int
intStringifier :: MyStringifier Int
superNumberStringifier :: MyStringifier MySuperNumber
import Data.Functor.Contravariant
newtype Trace m message = Trace { tracing :: message -> m () }
instance Contravariant (Trace m) where
contramap f tracer = Trace (tracing tracer . f)
newtype MySuperNumber = MySuperNumber Int
main :: IO ()
main = do
let intTracer :: Trace IO Int
intTracer = Trace print
someFunc :: MySuperNumber -> Int
someFunc (MySuperNumber i) = i * 10
superNumberTracer :: Trace IO MySuperNumber
superNumberTracer = contramap someFunc intTracer
actualTracer = tracing superNumberTracer
actualTracer $ MySuperNumber 12
someFunc
didn't change, even if we use Trace
with IO
!
main :: IO ()
main = do
c <- defaultConfigStdout
tr :: Trace IO String <- setupTrace (Right c) "simple"
logDebug tr "this is a debug message"
[iohk.simple:Debug:ThreadId 4] [2019-03-27 21:37:24.66 UTC] "this is a debug message"
data D = D { ss :: String, ii :: Int }
deriving (Generic, Show, Eq, Ord, FromJSON, ToJSON)
main :: IO ()
main = do
c <- defaultConfigStdout
tr :: Trace IO D <- setupTrace (Right c) "simple"
logDebug tr (D "this is a crazy debug message" 12)
[iohk.simple:Debug:ThreadId 4] [2019-03-27 21:37:24.66 UTC] D {ss = "this is a crazy debug message", ii = 12}
The end (for now...)