我正在尝试为以下Functor
定义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
and我将应用f
。
您正在尝试将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
类型的值。
它是一个无限类型,因为在这种情况下,我们将f :: (a -> b)
应用于具有BTree a
类型的左右子树。
这迫使a
与BTree a
相同,这将需要a
为无限类型(为了记录,你可以定义为Fix BTree
,其中Fix f = Fix (f (Fix f))
,这可能是有用的,但不是你想要的!)