我很难理解函数如何成为单子。
根据在 Control.Monad.Instances 中的声明,函数 (->) r 是一个单子。
即使Miran Lipovača在这里所说的也让我感到困惑:
实现" >>= "有点神秘,但其实并不是那样。当我们使用" >>= "将monadic value传递给function时,结果总是一个monadic value。因此,在这种情况下,当我们将一个function提供给另一个function时,结果也是一个function。这就是为什么结果最初以lambda开头的原因。到目前为止,所有" >>= "的实现都以某种方式将结果与monadic value隔离开来,然后将函数f应用于该结果。这里也发生了同样的事情。要从function获取结果,我们必须将其应用于某些内容,这就是为什么我们在这里执行(h w)以从function获取结果,然后我们将f应用于该结果。f返回一个monadic value,在我们的情况下是一个function,因此我们也将其应用于w。
(>>=)的类型签名是这样的: (>>=) :: m a -> (a -> m b) -> m b
所以我认为h的类型为m a,f的类型为(a -> m b)。如果一个function是m a,它会返回一个a类型的值吗?还是返回其他东西,需要一个a类型的值?
如果将h的非monad value提供给f,则我们会得到: f (h w) 看起来不错。由于f是一个function并且已经获取了它的唯一参数,它已经是一个value了,不是吗?由于它是一个monadic function,所以该值也是一个monadic value。为什么它还需要另一个值w?将w提供给f something不会使其变成非monadic吗,即它不再是一个function了吗?我也无法理解为什么f something和h使用相同的参数w并返回不同的值类型(m a和m b)。
根据在 Control.Monad.Instances 中的声明,函数 (->) r 是一个单子。
instance Monad ((->) r) where
return x = \_ -> x
h >>= f = \w -> f (h w) w
即使Miran Lipovača在这里所说的也让我感到困惑:
实现" >>= "有点神秘,但其实并不是那样。当我们使用" >>= "将monadic value传递给function时,结果总是一个monadic value。因此,在这种情况下,当我们将一个function提供给另一个function时,结果也是一个function。这就是为什么结果最初以lambda开头的原因。到目前为止,所有" >>= "的实现都以某种方式将结果与monadic value隔离开来,然后将函数f应用于该结果。这里也发生了同样的事情。要从function获取结果,我们必须将其应用于某些内容,这就是为什么我们在这里执行(h w)以从function获取结果,然后我们将f应用于该结果。f返回一个monadic value,在我们的情况下是一个function,因此我们也将其应用于w。
(>>=)的类型签名是这样的: (>>=) :: m a -> (a -> m b) -> m b
所以我认为h的类型为m a,f的类型为(a -> m b)。如果一个function是m a,它会返回一个a类型的值吗?还是返回其他东西,需要一个a类型的值?
如果将h的非monad value提供给f,则我们会得到: f (h w) 看起来不错。由于f是一个function并且已经获取了它的唯一参数,它已经是一个value了,不是吗?由于它是一个monadic function,所以该值也是一个monadic value。为什么它还需要另一个值w?将w提供给f something不会使其变成非monadic吗,即它不再是一个function了吗?我也无法理解为什么f something和h使用相同的参数w并返回不同的值类型(m a和m b)。
>>=
的行为才能理解do
符号中每一行对该单子所代表的含义。 - Dan BurtonApplicative
实例最容易解释和理解,因为“环境”始终是第一个参数,而Monad
实例等效于参数顺序。 - C. A. McCann