Haskell 无法使用函子构造无限类型
我试图为以下Haskell 无法使用函子构造无限类型,haskell,functor,Haskell,Functor,我试图为以下类型定义Functor、Applicative和Monad的实例: 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) 什么起作用了 f
类型定义Functor
、Applicative
和Monad
的实例:
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
的一个实例,表单必须被保留fa
->fb
(在我们的例子中是节点
)。
在我的实现中,您将得到fa->b
我不明白的是:
为什么它是无限类型?
考虑到节点(fa)(fb)
在层次结构的某个地方,子节点将是叶
,我将对其应用f
。它是一个无限类型,因为在这种情况下,我们将f::(a->b)
应用于类型为BTree a
的左右子树
这迫使a
与b树a
相同,这要求a
是一个无限类型(记录在案,您可以定义为Fix BTree
,其中Fix f=Fix(f(Fix f))
,这可能有用,但不是您想要的!)它是一个无限类型,因为在这种情况下,我们将f::(a->b)
应用于类型为b树a
的左右子树
这迫使a
与b树a
相同,这要求a
是一个无限类型(为了记录,您可以定义为Fix BTree
,其中Fix f=Fix(f(Fix f))
,这可能有用,但不是您想要的!)您正试图将f
应用于a
类型的值(在Leaf(ft)
中)和BTree a
类型的值(在节点(fa)(fb)
)。为此,类型检查器需要找到某种方法来统一a
和BTree a
,这只有在a
是BTree
类型的无限嵌套堆栈时才可能;在a
上再添加一层BTree
并不能有效地改变它
将Node(fa)(fb)
更改为Node(fmap fa)(fmap fb)
可确保f
仅应用于a
类型的值f
您试图将f
应用于a
类型的值(在Leaf(ft)
中)和BTree a
类型的值(在节点(fa)(fb)中)。为此,类型检查器需要找到某种方法来统一a
和BTree a
,这只有在a
是BTree
类型的无限嵌套堆栈时才可能;在a
上再添加一层BTree
并不能有效地改变它
将节点(f a)(f b)
更改为节点(fmap f a)(fmap f b)
可确保f
仅应用于a
类型的值