我对Haskell非常陌生,对语言的"架构"印象深刻,但是我仍然困扰着monad是如何纯粹的.
由于你有任何指令序列,它使它成为一个不纯的函数,尤其是 I/O函数从任何角度来看都不是纯粹的.
是因为Haskell像所有纯函数一样假设IO函数也有返回值,但是以操作码的形式还是什么?我真的很困惑.
我对(>>=)Haskell中绑定函数的定义有一些疑问.
因为Haskell是一种纯语言,所以我们可以使用Monad来处理带副作用的操作.我认为这个策略是有点像把所有的动作可能会引起副作用另一个世界,我们可以从"纯"哈斯克尔世界虽然控制它们do或>>=.
所以当我看一下>>=函数的 定义时
(>>=) :: Monad m => m a -> (a -> m b) -> m b
Run Code Online (Sandbox Code Playgroud)
它需要一个(a -> m b)函数,因此m a前一个动作的结果可以"解包"到非monadic a中>>=.然后,该功能(a -> m b)需要a作为其输入和返回另一个单子m b作为其结果.通过绑定功能,我可以对monadic进行操作,而不会给纯haskell代码带来任何副作用.
我的问题是为什么我们使用一个(a -> m b)函数?在我看来,一个m a -> m b函数也可以做到这一点.有什么理由,还是因为它的设计是这样的?
编辑
从意见,我知道这是很难提取a的m a.但是,我认为我可以将monadic m a视为a副作用.
是否有可能假设函数m a -> m b …
这是 kleisli 组合的常见实现:
kleisli :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
kleisli = \f g x -> f x >>= g
Run Code Online (Sandbox Code Playgroud)
为什么它不期望 monadic 上下文中的值呢?我相信有一个很好的理由。我只是没能看到它。
kleisli' :: Monad m => (a -> m b) -> (b -> m c) -> m a -> m c
kleisli' = \f g x -> x >>= f >>= g
Run Code Online (Sandbox Code Playgroud)
该类型似乎更易于组合,并且return可以在调用站点上只有纯值的情况下使用。