我想知道为什么下面是对类型的正确实现。具体来说,为什么Pair b a而不是Pair a b
newtype Pair b a = Pair { getPair :: (a,b) } 澄清一下,Pair a b不适用于以下方面:
instance Functor (Pair c) where  
fmap f (Pair (x,y)) = Pair (f x, y) 我不明白为什么。
除了下面的许多很好的答案之外,我发现在ghci中做以下工作很有帮助:
*Main> newtype Pair b a = Pair (a, b) deriving (Show, Eq)
*Main> :t Pair(True, "cat")
Pair(True, "cat") :: Pair [Char] Bool
*Main> newtype Pair a b = Pair (a, b) deriving (Show, Eq)
*Main> :t Pair(True, "cat")
Pair(True, "cat") :: Pair Bool [Char]发布于 2015-04-27 13:04:30
你说的是LYAH中的定义
newtype Pair b a = Pair { getPair :: (a,b) }  注意前面的段落(我的强调):
事实证明,为这个实例编写实例是有点困难的。对于
Maybe,我们只说实例函子,因为只有一个参数的类型构造函数才能成为函子的实例。但是,在使用(a,b)fmap**.时,似乎没有办法对进行类似的操作,因此类型参数a最终会发生变化为了解决这个问题,我们可以通过这样一种方式来创建我们的元组,即第二个类型参数表示元组中第一个组件的类型:**
因此,在本例中,我们希望(基础)对的第一个元素的类型是类型构造函数Pair中的最后一个类型。毕竟,我们希望对LYAH中的第一个参数使用fmap:
--                     b 
--                     |
--                     v  a isn't here… 
instance Functor (Pair c) where  
  -- but here!
  --fmap :: (a -> x) -> Pair c a -> Pair c x                        
    fmap f (Pair (x,y)) = Pair (f x, y)  当然,您可以将定义更改为newtype Pair b a = Pair { getPair :: (a,b) }。但在这个案子里会发生什么?
--                     a 
--                     |
--                     v  b isn't here… 
instance Functor (Pair c) where  
  -- but here!               v---- c ----v--------------------------+
  --fmap :: (b -> x) -> Pair c b -> Pair c x                        |
    fmap f (Pair (x,y)) = Pair (f x, y)                   --        |
                             -- ^^^ uh-oh - that doesn't seem right-+请记住,您的基础类型现在是(a,b)。但是,在您的Functor实例中,a现在是固定的,但是您尝试将fmap应用于此。这不管用。相反,您必须在第二个条目上使用fmap,它对应于类型构造函数Pair a b中的b。
--                     a 
--                     |
--                     v  b isn't here… 
instance Functor (Pair c) where  
  -- but here!
  --fmap :: (b -> x) -> Pair c b -> Pair c x
    fmap f (Pair (x,y)) = Pair (x, f y) 
                 --                ^^^ everything fine now.但此时,我们回到了最初的(a,b)实例。
发布于 2015-04-27 12:52:06
newtype Pair a b和newtype Pair b a都是正确的(就像它们键入check一样)。在后一种情况下,第二种元素的类型是第一种,这有悖于直觉,尽管它在用例中可能更合适。
https://stackoverflow.com/questions/29896327
复制相似问题