So let's say I want to define a newtype that houses a function:
newtype Test m a = Test(m -> (a, m))
This could be used to house state of some sort.
Now let's say I would like to implement fmap for this newtype.
instance Functor (Test m) where
--fmap :: (a -> b) -> Test m a -> Test m a -> b
fmap f (Test f1) (Test f2) = ?
Since the newtype houses functions there's no way to use pattern matching to break f1 and f2 apart.
For instance I initially thought maybe I could pass the input value of f2 into the call f1 to yield a (a, m) tuple, but I don't think you can do that.
ie
tup = f1 (get input of f2)
Is anyone able to provide me with what concepts I'm missing to deal with this scenario or is this just not possible?
Thanks
UPDATE
Big thanks to Redu and Willem Van Onsem.
Looks like I was lacking in understanding of how to use the composition operator (.).
Basically the key here is use (.) to grab the first element of the tuple and then do a bunch of partial function definitions to get into the state needed by fmap. Here is my fmap implementation without using the library function. Purposefully verbose to help with understanding.
alterParamStateHelper :: (a -> b) -> (m -> a) -> m -> (b, m)
alterParamStateHelper f1 f2 m = (b, m)
where
a = f2 e
b = f1 a
alterParamState :: (a -> b) -> (m -> (a, m)) -> (m -> (b, m))
alterParamState f1 f2 = alterParamStateHelper f1 h1
where
h1 = fst . f2--m -> a
instance Functor (Test m) where
-- fmap :: (a -> b) -> Test m a -> Test m b
fmap f1 (Test f2) = Test (alterParamState f1 f2)