在递归类型上实现monad

时间:2019-05-13 19:06:04

标签: haskell monads

我有一个递归类型:
data E a=A a (E a) (E a) | None
我的问题如下:
如果我想实现bind运算符,那么我该如何对具体类型和递归运算符进行操作?

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

对于我来说,在>>=上将A a (E a) (E a)上的a应用于function,看来我需要使用定制的{f x}对其进行包装。

我该如何解决f x以便解开E的结果以适合a-> ma的具体位置的情况

我需要一种可以使用功能的方法:(ma ->a)并将其保存到 unwrap::E a->a unwrap None= what here ? ( i need a neutral element for any kind of a) unwrap (A x _ _)=x

ViewHolder.getAdapterPosition() == position

1 个答案:

答案 0 :(得分:3)

要克服您的特定挑战,您应该尝试对f x的结果进行模式匹配。

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

现在,您遇到的问题可能比所遇到的问题更大。现在有太多的选择,而不是贫穷的选择。在A y my情况下,必须以某种方式将ymymx组合到最终结果中。您想到的大多数方式很可能会违反法律。

在这种情况下,很难知道该怎么做。除非我清楚数据类型的含义,否则我很难实现monad。我可以将列表“可视化”为单子,因为join(又名(>>= id))只是串联

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

但是对于任意代数数据类型,没有明确的路径。该数据类型从何而来? -您想从其monad实例获得什么?