Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.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
Haskell 绑定和连接之间的关系是什么?_Haskell_Monads_Category Theory - Fatal编程技术网

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

Haskell 绑定和连接之间的关系是什么?,haskell,monads,category-theory,Haskell,Monads,Category Theory,我得到的印象是,(>>=)(Haskell使用)和join(数学家首选)是“相等的”,因为一个人可以根据另一个人来写一个: import Control.Monad (join) join x = x >>= id x >>= f = join (fmap f x) 此外,由于bind可用于替换fmap: fmap f x = x >>= (return . f) 我有以下问题: 对于join,是否有fmap的(非递归)定义?(fmap fx=join$

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

import Control.Monad (join)

join x = x >>= id
x >>= f = join (fmap f x)
此外,由于
bind
可用于替换
fmap

fmap f x = x >>= (return . f)
我有以下问题:

  • 对于
    join
    ,是否有
    fmap
    的(非递归)定义?(
    fmap fx=join$fmap(return.f)x
    遵循上述等式,但是递归的。)

  • “每个单子都是函子”是使用
    bind
    (在单子的定义中)时的结论,还是使用
    join
    时的假设

  • bind
    join
    更“强大”吗?“更强大”意味着什么

  • 单子可以是:

    • return::a->ma
    • bind::ma->(a->mb)->mb
    或者,在以下方面:

    • return::a->ma
    • fmap::(a->b)->ma->mb
    • join::m(ma)->ma
    关于你的问题:

  • 不,我们不能根据
    join
    定义
    fmap
    ,因为否则我们可以从上面的第二个列表中删除
    fmap
  • 不,“每个单子都是一个函子”是一个关于单子的陈述,不管你是用
    bind
    还是用
    join
    fmap
    来定义你的单子。如果你看到第二个定义,你会更容易理解这句话,但仅此而已
  • 是的,
    bind
    join
    更“强大”。它与
    join
    fmap
    的组合完全一样“强大”,如果“强大”的意思是它有能力定义monad(总是与
    return
    结合使用)
  • 有关直觉,请参见,例如–
    bind
    允许您将策略/计划/计算(在上下文中)组合或链接在一起。例如,让我们使用
    Maybe
    上下文(或
    Maybe
    monad):

    fmap
    还可以让您将上下文中的计算链接在一起,但代价是每一步都增加嵌套。[1]

    λ: fmap plusOne (Just 3)
    Just (Just 4)
    
    这就是为什么您需要
    join
    :将两个嵌套级别压缩为一个。记住:

    join :: m (m a) -> m a
    
    只有挤压步骤并不能让你走得很远。您还需要
    fmap
    来拥有monad–和
    return
    ,在上面的示例中,这是
    只是

    [1] :
    fmap
    (>>=)
    不要将它们的两个参数按相同的顺序排列,但不要让它们混淆了你的意思

    join
    方面是否有
    fmap
    的[定义]

    不,没有。这可以通过尝试来证明。假设给我们一个任意类型的构造函数
    T
    ,函数:

    returnT :: a -> T a
    joinT :: T (T a) -> T a
    
    仅从这些数据,我们就要定义:

    fmapT :: (a -> b) -> T a -> T b
    
    让我们来画一个草图:

    fmapT :: (a -> b) -> T a -> T b
    fmapT f ta = tb
        where
        tb = undefined  -- tb :: T b
    
    我们需要以某种方式获得类型为
    tb
    的值<代码>ta::ta本身无法实现,因此我们需要生成
    TB
    值的函数。仅有的两个候选者是
    joinT
    returnT
    <代码>关节没有帮助:

    fmapT :: (a -> b) -> T a -> T b
    fmapT f ta = joinT ttb
        where
        ttb = undefined  -- ttb :: T (T b)
    
    它只是把问题解决了,因为在这种情况下需要一个
    T(tb)
    值并没有什么改善

    我们可以尝试使用
    returnT

    fmapT :: (a -> b) -> T a -> T b
    fmapT f ta = returnT b
        where
        b = undefined  -- b :: b
    
    现在我们需要一个
    b
    值。唯一能给我们的是
    f

    fmapT :: (a -> b) -> T a -> T b
    fmapT f ta = returnT (f a)
        where
        a = undefined  -- a :: a
    
    现在我们陷入困境:没有什么能给我们一个
    a
    。我们已经用尽了所有可能的方法,因此不能用这样的术语定义
    fmapT

    题外话:使用这样的函数作弊是不够的:

    extractT :: T a -> a
    
    使用
    extract
    ,我们可以尝试
    a=extract ta
    ,从而导致:

    fmapT :: (a -> b) -> T a -> T b
    fmapT f ta = returnT (f (extractT ta))
    
    然而,
    fmapT
    只有正确的类型是不够的:它还必须遵循函子定律。特别是,
    fmapT id=id
    应保持不变。根据此定义,
    fmapT id
    returnT。extract
    ,一般来说,它不是
    id
    (作为
    Monad
    Comonad
    实例的大多数函子都作为示例)


    “每个单子都是函子”是使用
    bind
    (在单子的定义中)时的结论,还是使用
    join
    时的假设

    “每个单子都是函子”是一个假设,或者更准确地说,是单子定义的一部分。选择一个任意的例子,这里是艾米丽·里尔,p。154:

    定义5.1.1。类别C上的单子包含

    • 内函子T:C→ C

    • a单位自然变换η:1C⇒ T、 及

    • a乘法自然变换μ:T2⇒ T,

    所以下面的图表在CC中交换:[单子定律图表]

    因此,根据定义,单子包含一个内函子。对于实例化
    Monad
    的Haskell类型构造函数
    T
    ,该内函子的对象映射是
    T
    本身,态射映射是其
    fmap
    T
    将是一个
    函子
    实例,因此将有一个
    fmap
    ,在当代Haskell中,由
    Applicative
    (扩展为
    函子
    )作为
    Monad
    的超类来保证

    但这就是故事的全部吗?就哈斯克尔而言。我们知道它是存在的,而且在不久的过去,函子不是
    单子
    的超类。这两个事实仅仅是哈斯卡尔主义吗?不完全是。在这篇经典论文中,尤金尼奥·莫吉揭示了以下定义(第3页):

    定义1.2([Man76])类别上的Kleisli三元组
    fmapT :: (a -> b) -> T a -> T b
    fmapT f ta = returnT (f (extractT ta))
    
    class KleisliTriple t where
        return :: a -> t a
        (=<<) :: (a -> t b) -> t a -> t b
    
    -- (return =<<) = id
    -- (f =<<) . return = f
    -- (g =<<) . (f =<<) = ((g =<<) . f =<<)