I have a datatype defined as
data Foo a = Foo a (a -> a)
The Foo
data constructor has two parameter value and function. I need to write Monad and Monad transform instance for this.
I am trying to implement functor instance,
instance Functor Foo where
fmap f (Foo x g) = Foo (f x) (g .(f x))
but I got an error Couldn't match type ‘a’ with ‘b’
.
This is correct because g
only accepts of type a
and f x
will convert a->b
.So next I rewrote as
instance Functor Foo where
fmap f (Foo x g) = Foo (f x) g
I got the same error "Couldn't match type ‘a’ with ‘b’".
I also tried this
instance Functor Foo where
fmap f (Foo x g) = Foo (f x) (f. g x)
I got Occurs check: cannot construct the infinite type: a ~ b -> a
for (g.x)
I am stuck, I know function g
only accepts of type a
and returns type a
. but fmap
will convert type a
to type b
. I think I have to apply fmap
over g
as well, which I am not able to do.
How do I write the instance for the above datatype?
Foo b (b -> b)
, but you never transformb
toa
, hence you can not use thea -> a
of the originalFoo
to construct a functionb -> b
. Except for theid
function (i.e.foo (f x) id
), you can notfmap
it, but likely that will not hold with the functor laws. – Willem Van Onsemg x
should then have typeb -> a
, but it has typea
, ifb -> a
is the same type asa
then this would result in an infinite recursive typeb -> (b -> (b -> ...)))
. – Willem Van Onsemfmap
: it would have to have type signaturefoomap :: (a -> b) -> (b -> a) -> Foo a -> Foo b
. – bradrn