I'm trying to understand how Free monads work in Haskell, and for that I've been trying to make an example work. My code was based on the answer here by Philip JF. Here is the example:
data Free f a = Pure a | Roll (f (Free f a))
--it needs to be a functor
instance Functor f => Functor (Free f) where
fmap f (Pure a) = Pure (f a)
fmap f (Roll x) = Roll (fmap (fmap f) x)
--this is the same thing as (++) basically
concatFree :: Functor f => Free f (Free f a) -> Free f a
concatFree (Pure x) = x
concatFree (Roll y) = Roll (fmap concatFree y)
data F a = One a | Two a a | Two' a a | Three Int a a a
deriving Show
-- Lift F into the Free monad
type FreeF a = Free F a
tree :: FreeF String
tree = Roll (One (Pure "A"))
example1 :: F (FreeF String)
example1 = One (Roll (One (Pure "A")))
The code above works. What I then wanted to do was to come up with a FreeF (f (FreeF a))
in order to apply the concatFree
function to it. Here is where I get into trouble.
result :: FreeF (FreeF String)
result = Roll (One (Roll (One (Pure "A"))))
The code above does not work. For me, it would seem that this construction was correct. What am I missing?
To be more precise, when I try to run this with ghci, I get the error:
FreeMonads3.hs:25:10: error:
• Couldn't match type ‘[Char]’ with ‘Free F String’
Expected type: FreeF (FreeF String)
Actual type: Free F [Char]
• In the expression: Roll (One (Roll (One (Pure "A"))))
In an equation for ‘result’:
result = Roll (One (Roll (One (Pure "A"))))
|
25 | result = Roll (One (Roll (One (Pure "A"))))