gpt4 book ai didi

haskell - 关于上下文中的值(应用于 Monad)

转载 作者:行者123 更新时间:2023-12-01 12:29:31 31 4
gpt4 key购买 nike

我有一个关于 value in context 的小问题。

  • Just 'a',所以在这种情况下 Maybe 类型上下文中的值是 'a'

  • 采用[3],因此在这种情况下,[a] 类型上下文中的值为3

  • 如果像这样为 [3] 应用 monad:[3] >>=\x -> [x+3],它意味着您将值 3 分配给 x。没关系。

但是现在,采用[3,2],那么[a]类型的上下文中的值是多少?。奇怪的是,如果你像这样为它应用 monad:

[3,4] >>= \x -> x+3  

它得到了正确的答案 [6,7],但实际上我们不明白在这种情况下 x 是什么。你可以回答,啊 x 是 3 然后是 4,并且 x 将函数提供 2 次并像 Monad 那样进行连接:concat (map f xs) 像这样:

[3,4] >>= concat (map f x) 

所以在这种情况下,[3,4] 将被分配给 x。这意味着错误,因为 [3,4] 不是一个值。 Monad 是错误的。

最佳答案

我认为您的问题是过于关注值(value)观。 monad 是一种类型构造函数,因此不关心值的数量和类型,而上下文。

A Maybe a 可以是 a,也可以什么都不是。很简单,您正确地观察到了这一点。

一个 Either String a 要么是一些 a,要么是一些 String 形式的信息(例如,为什么计算 >a 失败)。

最后,[a] 是未知数量的 a(或者根本没有),这可能是由于计算不明确,或者一个给出了多个结果(就像一个二次方程)。


现在,对于 (>>=) 的解释,了解 monad 的基本属性(类别理论家如何定义它)是有帮助的

join :: m (m a) -> m a.

fmap一起,(>>=)可以用join来写。

join 的含义如下:一个上下文,再次放入相同的上下文,仍然具有相同的结果行为(对于这个 monad)。

这对于 Maybe(Maybe a) 来说非常明显:Something 本质上可以是 Just (Just x),或者 Nothing,或者 Just Nothing,它提供与 Nothing 相同的信息。因此,不用Maybe (Maybe a),您可以只使用Maybe a,这样您就不会丢失任何信息。这就是 join 所做的:它转换为“更简单”的上下文。

[[a]] 在某种程度上更难,但并不多。您基本上从多个/模棱两可的结果中得到多个/模棱两可的结果。一个很好的例子是四次多项式的根,它是通过求解二次方程得到的。您首先得到两个解决方案,然后从每个解决方案中找到另外两个解决方案,从而得到四个根。

但重点是,你说的是模棱两可的模棱两可的结果,还是只是模棱两可的结果,都没有关系。您可以始终使用“模棱两可”的上下文,并使用 join 转换多个级别。

这就是 (>>=) 对列表所做的事情:它将不明确的函数应用于不明确的值:

squareRoots :: Complex -> [Complex] 

fourthRoots num = squareRoots num >>= squareRoots

可以重写为

fourthRoots num = join $ squareRoots `fmap` (squareRoots num)
-- [1,-1,i,-i] <- [[1,-1],[i,-i]] <- [1,-1] <- 1

因为您所要做的就是为每个可能的值找到所有可能的结果。

这就是为什么 join 是列表的 concat,事实上

m >>= f == join (fmap f) m

必须包含在任何 monad 中。

可以对IO 给出类似的解释。有副作用的计算,也可能有副作用 (IO (IO a)),本质上只是有副作用的东西

关于haskell - 关于上下文中的值(应用于 Monad),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13532048/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com