Haskell中违反函子规则的示例

Haskell中违反函子规则的示例,haskell,functor,Haskell,Functor,我有一个二叉树的数据结构和一个函子 data BST a = Empty | Node (BST a) a (BST a) instance Functor BST where fmap f Empty = Empty fmap f (Node l val r) = (Node (fmap f l) (f val ) (fmap f r)) 我需要找到一个BST实例和函数f的例子,其中函子的规则(身份、组合)被违反 有人能给我指一下正确的方向吗 谢谢 你找不到任何例子,因为你的定义

我有一个二叉树的数据结构和一个函子

data BST a = Empty | Node (BST a) a (BST a)
instance Functor BST  where
  fmap f Empty = Empty
  fmap f (Node l val r) = (Node (fmap f l) (f val  ) (fmap f r))
我需要找到一个BST实例和函数f的例子,其中函子的规则(身份、组合)被违反

有人能给我指一下正确的方向吗


谢谢

你找不到任何例子,因为你的定义包含函子定律。你可以通过归纳树的深度来证明它。基本情况是0深度树(即
),然后证明
节点
情况。证据很长,但很简单

编辑: 重新阅读您的问题,可能您正在寻找
fmap
的定义,该类型检查不符合funtor定律。只用

data BST a = Empty | Node (BST a) a (BST a)
instance Functor BST  where
  fmap f Empty = Empty
  fmap f (Node l val r) = (Node (fmap f r) (f val  ) (fmap f l))
--                                      |- notice            |- notice
为什么它不遵守法律?你请客。下面是你的定义确实成立的证据。试着建立你自己的证据来证明为什么我的定义不成立

第一定律 基本情况 递归案例 假设给定深度
D
(或更小)的所有树的变形均为真。树的一个深度的证明
(D+1)

第二定律 基本情况 递归案例 假设给定深度
D
(或更小)的所有树的变形均为真。树的一个深度的证明
(D+1)


你找不到任何例子,因为你的定义包含函子定律。你可以通过归纳树的深度来证明它。基本情况是0深度树(即
),然后证明
节点
情况。证据很长,但很简单

编辑: 重新阅读您的问题,可能您正在寻找
fmap
的定义,该类型检查不符合funtor定律。只用

data BST a = Empty | Node (BST a) a (BST a)
instance Functor BST  where
  fmap f Empty = Empty
  fmap f (Node l val r) = (Node (fmap f r) (f val  ) (fmap f l))
--                                      |- notice            |- notice
为什么它不遵守法律?你请客。下面是你的定义确实成立的证据。试着建立你自己的证据来证明为什么我的定义不成立

第一定律 基本情况 递归案例 假设给定深度
D
(或更小)的所有树的变形均为真。树的一个深度的证明
(D+1)

第二定律 基本情况 递归案例 假设给定深度
D
(或更小)的所有树的变形均为真。树的一个深度的证明
(D+1)



在我看来,这种实施是正确的,我的意思是,它应该尊重这两项法律。你确定你从任何地方都正确地复制了这个练习吗?你的练习是定义一个新的函子实例吗?另一种可能性,尽管我认为不太可能:虽然这个实现是Hask上的函子,但名称“BST”表明你在处理二进制搜索树,其中有数据类型不变量。这种实现不一定保留这些不变量,也许可以通过指出它不是
Ord
ered类型和单调函数子类别上的函子来表示。但这是一个相当严重的延伸——你需要阅读一篇相当高级的文章,才能明智地谈论这一点。@GilShafriri如果你还控制
Functor
实例,然后编写一个不同的、更复杂的实例。这个实现在我看来是正确的,我的意思是,它应该尊重这两条法律。你确定你从任何地方都正确地复制了这个练习吗?你的练习是定义一个新的函子实例吗?另一种可能性,尽管我认为不太可能:虽然这个实现是Hask上的函子,但名称“BST”表明你在处理二进制搜索树,其中有数据类型不变量。这种实现不一定保留这些不变量,也许可以通过指出它不是
Ord
ered类型和单调函数子类别上的函子来表示。但这是一个相当严重的延伸——你需要阅读一篇相当高级的文章,才能明智地谈论这个问题。@GilShafriri如果你也控制
Functor
实例,然后写一篇不同的文章,最后,我得到了一个确认,函子不应该违反任何函子法则,但他声称实现是“buggy”。为什么?因为BST在向函子提供某些函数f(例如(\x->(-x))后可以成为非BST。我很难接受这个“错误”术语,因为函子中任何违反某些不变量的行为都可以被视为“错误”。如果你提到@danielWagner comment。他声称你可以实现一个函子实例,使它变得有缺陷,而不是说这个实现有缺陷。一个有缺陷的实例就是我的答案编辑中的一个。什么意思变成“有缺陷”?函子可以改变它所操作的数据的一些不变量。我觉得“有缺陷”不是这个现实的正确术语。当然,我可以写一个违反法律的函子,但我觉得这不是很有趣。教授声称BST上的每个函子都是“虫子”。我有一个问题要同意。对不起,我迷路了。你的问题是“我能找到一个例子,在这个特定的类型和实例中,函子法则被违反了。”答案是不,你不能。所有这些“错误”问题与你的问题有什么关系?最后我得到确认,函子不应该违反任何函子法则,但他声称实现是“错误的”“。为什么?因为BST可以在向函子提供某些函数f(例如(\x->(-x))后成为非BST。我无法接受此“错误”术语,因为函子中任何违反某些不变量的行为都可以被视为“错误”。如果你提到@danielWagner comment。他声称你可以实现一个函子实例,使它成为有缺陷的,而不是说这个实现是有缺陷的。有缺陷的实例的一个例子就是我的答案编辑中的一个,这意味着什么变成“有缺陷”?函子可以改变一些不变量的
fmap id Empty = Empty    -- by definition of fmap
              = id Empty -- by definition of id
=> fmap id = id          -- by eta-reducing both sides of the equation
fmap id (Node l val r) = Node (fmap id l) (id val) (fmap id r) -- by definition of fmap
                       = Node (fmap id l) val      (fmap id r) -- by applying id to val
                       = Node l val r                          -- by induction hyp. fmap id l == l
                       = id (Node l val r)                     -- by definition of id
=> fmap id             = id                                    -- by eta-reducing both sides of the equation
 fmap g . fmap f == fmap (g . f)
-- Eq 1
(fmap g . fmap f) Empty = fmap g (fmap f Empty)  -- by definition of .
                        = fmap g Empty           -- by definition of fmap
                        = Empty                  -- by definition of fmap
-- Eq 2
fmap (g . f) Empty      = Empty                  -- by definition of fmap

-- Therefore
(fmap g . fmap f) Empty = fmap (g . f) Empty     -- By transition of equality on Eq1 and Eq2
fmap g . fmap f         = fmap (g . f)           -- by eta-reducing both sides of the equation
-- Eq 1
fmap (g . f) (Node l val r) = Node (fmap (g . f) l) 
                                   ((g . f) val) 
                                   (fmap (g . f) r) -- by definition of fmap

                            = Node ((fmap g . fmap f) l) 
                                   ((g . f) val) 
                                   ((fmap g . fmap f) r) -- by induction hyp.

-- Eq 2
(fmap g . fmap f) (Node l val r) = fmap g (fmap f (Node l val r)) -- dy definition of .
                                 = fmap g $ Node (fmap f l) 
                                                 (f val) 
                                                 (fmap f r)       -- by definition of fmap
                                 = Node (fmap g (fmap f l))
                                        (g (f val))
                                        (fmap g (fmap f r))       -- by definition of fmap
                                 = Node ((fmap g . fmap f) l) 
                                        ((g . f) val) 
                                        ((fmap g . fmap f) r)     -- by induction hyp.

fmap (g . f) (Node l val r) = (fmap g . fmap f) (Node l val r)    -- By transition of equality on Eq1 and Eq2
fmap (g . f)                = (fmap g . fmap f)                   -- by eta-reducing both sides of the equation