Haskell 文献中列表单子绑定的两种实现:为什么它们是等价的?

Haskell 文献中列表单子绑定的两种实现:为什么它们是等价的?,haskell,Haskell,阅读Graham Hutton第二版“Haskell中的编程”中的Monad一章,我在第167页找到了这个例子来说明列表Monad的行为: > pairs [1,2] [3,4] [(1,3),(1,4),(2,3),(2,4)] 对的定义如下: pairs :: [a] -> [b] -> [(a,b)] pairs xs ys = do x <- xs y <- ys return (

阅读Graham Hutton第二版“Haskell中的编程”中的Monad一章,我在第167页找到了这个例子来说明列表Monad的行为:

> pairs [1,2] [3,4]
[(1,3),(1,4),(2,3),(2,4)]    
对的定义如下:

pairs :: [a] -> [b] -> [(a,b)]
pairs xs ys = do x <- xs
                 y <- ys
                 return (x,y)
有了这个定义,我理解了这个例子为什么有效。 但第一个定义是我在《序曲》中找到的,所以我相信它是正确的

我的问题

  • 有人能解释为什么第一个定义等同于第二个定义吗?(第一节中的concat发生在哪里?)

    • 列表理解只是句法上的糖分。基本上,
      [fxy | x>=\y->返回(x,y)
      ≡ [p | x>=\y->返回(ξ,y))x]
      ≡ [p | x=\y->返回(x,y))]
      
      ≡ [p|x
      [y | x>=f

      太多了…我现在不得不慢慢咀嚼:-)但现在我意识到我对列表理解的理解太幼稚了:这真是一头野兽。谢谢你…现在我了解到列表理解中有一个隐含的concat。注意列表理解是单子理解的一个特例,它是do表示法的一种特殊语法,它是
      >=
      的特殊语法,在引擎盖下使用
      join
      。“隐式concat”通常是一元
      join::Monad m=>m(MA)->m a
      。是的,但是解释
      >=
      在理解和解释
      do
      -符号和
      >=
      方面是有点循环的。@Lazersmoke确实-
      (>=f)=join.fmap f
      与此相关。为了避免混淆,还值得一提的是,就目前情况来看,
      (>=)
      并没有真正地在引擎盖下使用
      join
      (当然也可以这样实现)。
      join x
      目前定义为
      x>=id
      @duplode我的意思是澄清一下“在引擎盖下”的意思是,
      join
      是monad的理论基础操作,
      >=
      只是定义它的一种很好的等效方法(使用标识
      join=(>>=id)
      instance Monad [] where
         -- (>>=) :: [a] -> (a -> [b]) -> [b]
         xs >>= f = [y | x <- xs, y <- f x]
      
      ...
         xs >>= f = concat (fmap f xs)
      
      concatMap (\x -> concatMap (\y -> return $ f x y) m) l
      
      concat $ fmap (\x -> concat $ fmap (\y -> return $ f x y) m) l
      
      pairs [1,2] [3,4]
       ≡ do { x <- [1,2]; y <- [3,4]; return (x,y) }
       ≡ [1,2] >>= \x -> [3,4] >>= \y -> return (x,y)
       ≡ [p | x<-[1,2], p <- (\ξ -> [3,4] >>= \y -> return (ξ,y)) x]
       ≡ [p | x<-[1,2], p <- ([3,4] >>= \y -> return (x,y))]
       ≡ [p | x<-[1,2], p <- [q | y<-[3,4], q <- (\υ -> return (x,υ)) y]]
       ≡ [p | x<-[1,2], p <- [q | y<-[3,4], q <- return (x,y)]]
       ≡ [p | x<-[1,2], p <- [q | y<-[3,4], q <- [(x,y)]]]
       ≡ [p | x<-[1,2], p <- [(x,3), (x,4)]]
       ≡ [(1,3), (1,4)] ++ [(2,3), (2,4)]
       ≡ [(1,3), (1,4), (2,3), (2,4)]