我有一个递归类型:
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
答案 0 :(得分:3)
要克服您的特定挑战,您应该尝试对f x
的结果进行模式匹配。
(>>=) (A x mx) f =
case f x of
A y my ->
B y ->
None ->
现在,您遇到的问题可能比所遇到的问题更大。现在有太多的选择,而不是贫穷的选择。在A y my
情况下,必须以某种方式将y
,my
和mx
组合到最终结果中。您想到的大多数方式很可能会违反法律。
在这种情况下,很难知道该怎么做。除非我清楚数据类型的含义,否则我很难实现monad。我可以将列表“可视化”为单子,因为join
(又名(>>= id)
)只是串联
join :: [[a]] -> [a]
join [ [ x, y ], [z], [], [w, q] ] = [x, y, z, w, q]
但是对于任意代数数据类型,没有明确的路径。该数据类型从何而来? -您想从其monad实例获得什么?