我正在尝试为以下Functor
的{{1}},Applicative
和Monad
定义实例:
type
我尝试过实现 data BTree a=Leaf a | Node (BTree a) (BTree a) deriving (Eq,Show)
实例,如下所示:
Functor
什么起作用
instance Functor BTree where
fmap f (Leaf t) =Leaf (f t)
fmap f (Node a b) =Node (f a) (f b)
我理解这是不正确的,因为作为fmap f (Node a b)=Node (fmap f a) (fmap f b)
的实例,必须保留functor
-> f a
(在我们的情况下为f b
)中。
在我的实现中,您将得到Node
。
我不了解的地方:
为什么是无限类型?
考虑到f a -> b
在层次结构中的某个位置,孩子Node (f a )(f b)
将是Node
,而我将对其应用Leaf
。
答案 0 :(得分:6)
您正在尝试将f
应用于类型a
(在Leaf (f t)
中的值和类型BTree a
(在Node (f a) (f b)
中的值)。为此,类型检查器需要找到某种方法来统一a
和BTree a
,只有在a
是BTree
类型的无限嵌套堆栈时才有可能。在BTree
之上再添加一层a
并不能有效地对其进行更改。
将Node (f a) (f b)
更改为Node (fmap f a) (fmap f b)
可以确保f
仅 应用于类型a
的值。
答案 1 :(得分:4)
这是一个无限类型,因为在这种情况下,我们将f :: (a -> b)
应用于类型为BTree a
的左右子树。
这将强制a
与BTree a
相同,这将要求a
为无限类型(根据记录,您可以将其定义为Fix BTree
,其中Fix f = Fix (f (Fix f))
,这可能很有用,但这里没有您想要的!)