相关疑难解决方法(0)

为什么绑定运算符 (>>=) 是这样定义的?

我已经学习 Haskell 几个星期了(只是为了好玩),刚刚观看了 Brian Beckman介绍 monad的精彩视频。他激励 monad 需要创建一个更通用的组合运算符。按照这个思路,如果我有两个功能:

f :: a -> b
g :: b -> c
Run Code Online (Sandbox Code Playgroud)

组合运算符应该满足

h = g . f :: a -> c
Run Code Online (Sandbox Code Playgroud)

由此我可以推断出正确的.运算符类型:

(.) : (b -> c) -> (a -> b) -> (a -> c)
Run Code Online (Sandbox Code Playgroud)

说到 monad,假设我有两个功能:

f :: a -> m b
g :: b -> m c
Run Code Online (Sandbox Code Playgroud)

在我看来,自然的选择是定义一个通用的组合运算符,其工作方式如下:

h = f >>= g :: a -> m c
Run Code Online (Sandbox Code Playgroud)

在这种情况下,>>=运算符的类型签名为:

(>>=) :: (a -> …
Run Code Online (Sandbox Code Playgroud)

monads haskell bind

69
推荐指数
4
解决办法
4369
查看次数

Monad加入功能

虽然monads在Haskell中使用bind和return函数表示,但它们也可以使用join函数进行另一种表示,如此处所述.我知道这个函数的类型是M(M(X)) - > M(X),但这实际上是做什么的?

monads haskell

26
推荐指数
4
解决办法
1万
查看次数

monad绑定(>> =)运算符更接近函数组合(链接)或函数应用程序吗?

在许多文章中我都读过monad >>=运算符是一种表示函数组合的方法.但对我来说,它更接近某种高级功能应用程序

($)   :: (a -> b) -> a -> b
(>>=) :: Monad m => m a -> (a -> m b) -> m b
Run Code Online (Sandbox Code Playgroud)

对于我们的构图

(.)   :: (b -> c) -> (a -> b) -> a -> c
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
Run Code Online (Sandbox Code Playgroud)

请澄清.

monads haskell functional-programming bind category-theory

18
推荐指数
2
解决办法
2797
查看次数

绑定和连接之间是什么关系?

我的印象是(>>=)(由Haskell使用)和join(由数学家首选)是“相等的”,因为一个人可以用另一个来写:

import Control.Monad (join)

join x = x >>= id
x >>= f = join (fmap f x)
Run Code Online (Sandbox Code Playgroud)

另外,每个monad都是函子,因为bind可以用来代替fmap

fmap f x = x >>= (return . f)
Run Code Online (Sandbox Code Playgroud)

我有以下问题:

  1. 是否有一个(非递归)的定义fmap来讲join?(fmap f x = join $ fmap (return . f) x根据上面的方程式,但是是递归的。)

  2. 使用时bind(在monad的定义中),“每个monad都是函子”是结论,而使用时是假设join吗?

  3. bind不是更“强大” join?“更强大”意味着什么?

monads haskell category-theory

9
推荐指数
2
解决办法
220
查看次数

哪种代数模式适合这种类型的树?

我有一个谜题,

我设法编写了一些使用递归方案来做这些事情的代码,但它非常混乱,这通常意味着我在某个地方错过了一个有用的抽象.

我正在为我的文本编辑器设计一个布局系统 Rasa; 它使用与Vim非常相似的方式进行拆分.我决定使用树来描述分裂; 您可以将它想象为垂直或水平分割的二叉树,在叶节点处具有"视图".这张照片 可能有帮助.

这是我的初始数据结构:

data Direction = Hor | Vert
data Tree a = 
  Branch Direction (Tree a) (Tree a)
  | Leaf a
  deriving (Functor)
Run Code Online (Sandbox Code Playgroud)

我需要的一些操作是:

  • split :: (View -> Tree View) -> Tree View -> Tree View 将节点(或不是)水平或垂直地分成两个节点(同时保持它们在树中的位置)
  • close :: (View -> Bool) -> Tree View -> Tree View 通过从树中删除它们并正确地重新组织相邻视图来"关闭"与谓词匹配的任何视图.
  • fmap; 我希望树能成为一个仿函数,所以我可以改变观点.

一些很好的功能: - focusRight :: Tree View -> Tree View,当且仅当左边最近的水平连接视图WAS处于活动状态时,才将视图设置为活动状态

我正在寻找一个抽象或一组抽象,以一种干净的方式提供这种功能.到目前为止,这是我的思考过程:

起初我以为我有一个Monoid,标识是空树, mappend只是将另一个分支附加到树上,但这不起作用,因为我有两个操作:垂直追加和水平追加,操作不是关联的当他们混在一起的时候.

接下来我想'我的一些操作取决于他们的背景'所以我可能有一个Comonad.我拥有的树的版本不能作为共同monad工作,因为我没有extract分支上的值,所以我重构了我的树,如下所示:

data Tree a …
Run Code Online (Sandbox Code Playgroud)

monads haskell comonad

8
推荐指数
1
解决办法
223
查看次数

使用monads,可以根据绑定来定义连接吗?

在Haskell中,monad是根据函数return和bind定义的,其中return有类型a -> m a,bind有类型m a -> (a -> m b) -> m b.之前已经指出monad也可以用return和join来定义,其中join是一个带有类型的函数m (m a) -> m a.绑定可以用连接来定义,但是反过来可能吗?可以在绑定方面加入定义吗?

没有加入,我不知道如果我以某种方式获得"两次包裹"的monadic值,我会做什么,m (m a)- 没有任何仿函数或monad操作"删除任何层",可以这么说.如果这是不可能的,为什么Haskell和许多其他monad实现在绑定方面定义它们?它似乎没有基于连接的定义有用.

monads haskell

6
推荐指数
4
解决办法
928
查看次数

为什么haskell的绑定函数从非monadic到monadic采用函数

我对(>>=)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函数也可以做到这一点.有什么理由,还是因为它的设计是这样的?

编辑

从意见,我知道这是很难提取am a.但是,我认为我可以将monadic m a视为a副作用.

是否有可能假设函数m a -> m b …

monads haskell

4
推荐指数
1
解决办法
569
查看次数

单子中的纯映射

假设我有两个功能

f :: Monad m => a -> m a
g :: a -> a
Run Code Online (Sandbox Code Playgroud)

我想连续应用于某些元素,如下所示:

(return x) >>= f >>= g
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为 g 是纯的,所以我首先需要“人为地”将它变成 monadic。一种可能性是

(return x) >>= f >>= (return . g)
Run Code Online (Sandbox Code Playgroud)

这对我来说不是很直观。另一种可能性是使用 Monad 是 Applicative:

(return g) <*> ((return x) >>= f)
Run Code Online (Sandbox Code Playgroud)

但这不是很直观,因为函数和参数的顺序不同:

(>>=) :: Monad m => m a -> (a -> m b) -> m b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)

处理这个问题的规范方法是什么?如果(>>==) = (flip …

monads haskell

4
推荐指数
2
解决办法
144
查看次数

为什么 kleisli 组合期望纯值?

这是 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可以在调用站点上只有纯值的情况下使用。

monads haskell composition kleisli

4
推荐指数
1
解决办法
230
查看次数

在Maybe / List monad中如何实现`join`?

join可以通过以下方式定义实现>>=

join :: Monad m => m (m a) -> m a
join m = m >>= id
Run Code Online (Sandbox Code Playgroud)

具体来说,如何在Maybe和List单声道中实现它?

是在monad中吗?

join Nothing = Nothing
join (Just (Just x)) = Just x
Run Code Online (Sandbox Code Playgroud)

在List monad中:

join [] = []
join [[xs]] = [xs]
Run Code Online (Sandbox Code Playgroud)

谢谢。

monads haskell

3
推荐指数
1
解决办法
102
查看次数