Bercovici Adrian
Bercovici Adrian

Reputation: 9370

Implementing monad on recursive type

I have a recursive type:
data E a=A a (E a) (E a) | None
My problem is the following :
If i want to implement the bind operator how do i operate on both the Concrete type and the recursive one given the function to operate with?

instance Monad E where
    return x= A x None None 
    (>>=) None _ = None
    (>>=) (B t) f =  f t
    (>>=) (A x mx my) f = A {f x} (mx>>=f)  (my>>=f) --here !!!
                               ^
                            result is ma but slot requires concrete type

For me to apply >>= on A a (E a) (E a) for the a it seems i need to unwrap it using a custom made function.

How do i solve the {f x}so that i unwrap the result of f x to fit in the concrete slot of the E

I would need for a method that can take a function: a-> ma and get it to (ma ->a)

    unwrap::E a->a
    unwrap None= what here ? ( i need a neutral element for any kind of a)
    unwrap (A x _ _)=x

Upvotes: 1

Views: 193

Answers (1)

luqui
luqui

Reputation: 60503

To overcome your specific challenge, you should try pattern matching on the result of f x.

(>>=) (A x mx) f = 
    case f x of
        A y my -> 
        B y -> 
        None -> 

Now you have perhaps a larger problem than the one you came in with. There are now too many choices, as opposed to a poverty of them. In the A y my case, you must combine y, my, and mx into the final result in some way. Very likely most of the ways you think of will violate the laws.

In this case it is hard to know what to do. It is hard for me to implement a monad unless I am clear about the meaning of the data type. I can "visualize" list as a monad because join (aka (>>= id)) is just concatenation

join :: [[a]] -> [a]
join [ [ x, y ], [z], [], [w, q] ] = [x, y, z, w, q]

But for an arbitrary algebraic data type there is no clear path. Where did this data type come from? -- what do you want from its monad instance?

Upvotes: 3

Related Questions