Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List Haskell Monad-列表中的Monad是如何工作的?_List_Haskell_Monads - Fatal编程技术网

List Haskell Monad-列表中的Monad是如何工作的?

List Haskell Monad-列表中的Monad是如何工作的?,list,haskell,monads,List,Haskell,Monads,为了理解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]

为了理解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]
但我不确定它是如何工作的。 例如:

[ y | y <- [[1],[2]]]
[[1],[2]]
[y | y([x+1])
[1,2,3]
的每个列表元素会导致
[2,3,4]
而不是
[2]、[3]、[4]


或者很简单,我的困惑似乎源于不理解“数学定义”如何比Haskell标准类的方法更容易理解这条语句

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]
、和更多描述单子列表

比较:

  • (=mb)->ma->mb
    用于具有
  • 对于
    m=[]
常规的
(>>=)
绑定操作符的参数是翻转的,但在其他方面,它只是一个中缀
concatMap

或者很简单,我的困惑似乎源于不理解这句话实际上是如何运作的:

(>>|) xs f = [ y | x <- xs, y <- f x ]
  • 这可以缩短(每行重写一次):

  • 因此,通过使用列表理解,您并没有真正声明一个新的定义,您只是依赖于现有的定义。如果需要,您可以定义您的
    实例Monadd[]
    ,而不依赖现有的Monad实例或列表理解:

    • 使用
      concatMap

      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)
      
    Monadd类型类应该有类似于
    return
    的内容。我不知道为什么会缺少它。

    就像嵌套循环一样:

       xs >>| foo = [ y | x <- xs, y <- foo x]
    
    --            =   for x in xs:
    --                         for y in (foo x):
    --                               yield y
    
    以上相当于

        concat (map foo [a,b,c,d]) 
        =  
        foo a ++ foo b ++ foo c ++ foo d
    
    对于一些适当的
    foo

    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 ]
    
    [a,b,c,d]
    /   \      |      |     /   \
    
    [a1,a2],[b1],[d1,d2]——fmap foo=[foo x | x你自己写的。
    (>>|)xs f=[y | x是的,看起来我不明白如何
    [y | x在这个表达式中写下x、xs、y和fx的类型应该是有帮助的。但是在我定义的
    Applicative
    Monadd
    实例中,它是如何工作的?或者更确切地说,
    join
    是如何在
    purea
    app
    中实现的
    ?好吧,通过加入elementwise应用结果。我想你没有意识到列表理解可以做到这一点(参见编辑,我展示了如何通过理解来实现
    加入
    )。虽然没有作弊。LCs恰好与一元代码等效,但是。
    instance Monadd [] where
      (>>|) [] f = []
      (>>|) (x:xs) f = let ys = f x in ys ++ ((>>|) xs f)
    
       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]
    
      [ 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
    
        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 ]