代码之家  ›  专栏  ›  技术社区  ›  coder_bro

哈斯凯尔·蒙纳德-单子在名单上是如何工作的?

  •  2
  • coder_bro  · 技术社区  · 7 年前

    为了理解Monad,我提出了以下定义:

    class Applicative' f where
     purea :: a -> f a
     app :: f (a->b) -> f a -> f b
    
    class Applicative' m =>  Monadd m where
     (>>|) :: m a -> (a -> m b) -> m b
    
    instance Applicative' [] where
     purea x = [x]
     app gs xs = [g x | g <- gs, x <- xs]
    
    instance Monadd [] where
     (>>|) xs f = [ y | x <-xs, y <- f x]
    

    按预期工作:

    (>>|) [1,2,3,4] (\x->[(x+1)])
    [2,3,4,5]
    

    但我不确定它是如何工作的。 例如:

    [ y | y <- [[1],[2]]]
    [[1],[2]]
    

    如何申请 (\x->([x+1]) 到的每个列表元素 [1,2,3] 导致 [2,3,4] 而不是 [[2],[3],[4]]

    或者很简单的说,我的困惑似乎是因为不理解这个说法 [ y | x <-xs, y <- f x] 实际有效

    3 回复  |  直到 6 年前
        1
  •  2
  •   sshine    7 年前

    Wadler School of Haskell LYAH HaskellWiki Quora

    (>>=) concatMap

    (>>|) xs f = [ y | x <- xs, y <- f x ]
    

    • (>>|) xs f = do x <- xs
                      y <- f x
                      return y
      
    • (>>|) xs f = xs >>= \x ->
                   f x >>= \y ->
                   return y
      
    •   (>>|) xs f = xs >>= \x -> f x >>= \y -> return y -- eta-reduction
      ≡ (>>|) xs f = xs >>= \x -> f x >>= return         -- monad identity
      ≡ (>>|) xs f = xs >>= \x -> f x                    -- eta-reduction
      ≡ (>>|) xs f = xs >>= f                            -- prefix operator
      ≡ (>>|) xs f = (>>=) xs f                          -- point-free
      ≡ (>>|) = (>>=)
      

    instance Monadd []

    • instance Monadd [] where
        (>>|) xs f = concatMap f xs
      
    • instance Monadd [] where
        (>>|) xs f = concat (map f xs)
      
    • instance Monadd [] where
        (>>|) [] f = []
        (>>|) (x:xs) f = let ys = f x in ys ++ ((>>|) xs f)
      

    return

        2
  •  2
  •   leftaroundabout    7 年前

    class Applicative' m => Monadd m where
      join :: m (m a) -> m a
    

    join mma = mma >>= id
    
    ma >>= f = join (fmap f ma)
    

    join concat

    join :: [[a]] -> [a]
    join xss = [x | xs <- xss, x <- xs]  -- xss::[[a]], xs::[a]
    -- join [[1],[2]] ≡ [1,2]
    

    [1,2,3,4] >>= \x->[(x+1)]
      ≡   join $ fmap (\x->[(x+1)]) [1,2,3,4]
      ≡   join [[1+1], [2+1], [3+1], [4+1]]
      ≡   join [[2],[3],[4],[5]]
      ≡   [2,3,4,5]
    
        3
  •  2
  •   Will Ness Derri Leahy    6 年前

    List comprehensions

       xs >>| foo = [ y | x <- xs, y <- foo x]
    
    --            =   for x in xs:
    --                         for y in (foo x):
    --                               yield y
    

    [1,2,3,4] >>| (\x -> [x, x+10])
    =
    [ y | x <- [1,2,3,4], y <- (\x -> [x, x+10]) x]
    =
    [ y | x <- [1] ++ [2,3,4], y <- [x, x+10]]
    =
    [ y | x <- [1], y <- [x, x+10]] ++ [ y | x <- [2,3,4], y <- [x, x+10]]  -- (*)
    =
    [ y |           y <- [1, 1+10]]   ++ [ y | x <- [2,3,4], y <- [x, x+10]]
    =
    [ y | y <- [1]] ++ [ y | y <- [11]] ++ [ y | x <- [2,3,4], y <- [x, x+10]]
    =
    [1] ++ [11] ++ [ y | x <- [2,3,4], y <- [x, x+10]]
    =
    [1, 11] ++ [2, 12] ++ [ y | x <- [3,4], y <- [x, x+10]]
    =
    [1, 11] ++ [2, 12] ++ [3, 13] ++ [ y | x <- [4], y <- [x, x+10]]
    =
    [1, 11] ++ [2, 12] ++ [3, 13] ++ [4, 14]
    

    (*)

    foo

      [ a,          [a1, a2] ++        concat [ [a1, a2],         [  a1, a2,
        b,    ==>   [b1]     ++    ==           [b1],        ==      b1,
        c,          []       ++                 [],
        d ]         [d1, d2]                    [d1, d2] ]           d1, d2  ]
    

        concat (map foo [a,b,c,d]) 
        =  
        foo a ++ foo b ++ foo c ++ foo d
    

    concat join map fmap

        m >>= foo  =  join (fmap foo m)
    

    [     a     ,  b   ,  c  ,    d      ]
        /   \      |      |     /   \
    [  [a1, a2] , [b1] ,  [] , [d1, d2]  ]  -- fmap foo    = [foo x | x <- xs]
                                            --             =     [y | x <- xs, y <- [foo x]]
    [   a1, a2  ,  b1  ,        d1, d2   ]  -- join (fmap foo) = [y | x <- xs, y <-  foo x ]