代码之家  ›  专栏  ›  技术社区  ›  pls

身份单子——哈斯克尔的行为差异?

  •  1
  • pls  · 技术社区  · 8 年前

    我最近在Haskell和Monads一起玩(这方面我还是个新手)。我遇到了一些有趣的行为(至少对我来说是有趣的) Identity Monad .


    如果我编写以下函数:

    let f = \x -> Identity 2 >>= \y -> x * y

    然后呢 :t 我明白了 f :: Num b => Identity b -> Identity b 1.推断x是一个 Identity (Num b) .我可以用 6 我得到了结果 12 .

    但是如果我用同样的方法 Maybe 就像这样:

    let g = \x -> Just 2 >>= \y -> x * y

    <interactive>:2096:5: error:
        • Non type-variable argument in the constraint: Num (Maybe b)
          (Use FlexibleContexts to permit this)
        • When checking the inferred type
            g :: forall b. Num (Maybe b) => Maybe b -> Maybe b
    

    因此,我需要明确地返回 大概 或使用 return .所以我: let g = \x -> Just 2 >>= \y -> return $ x * y .

    一切正常。然而,后来我开始想,到底发生了什么 Identity 蒙纳德。

    首先,我尝试添加显式返回类型,如下所示:

    let f = \x -> Identity 2 >>= \y -> Identity $ x * y

    然后呢 :t 又一次,我 f :: Num b => b -> Identity b .这是我第一次想到的。


    这让我想知道它是如何处理的 x + y 没有 Identity $ 如果是推断的话 x y 被包裹在 身份 .所以我尝试了以下方法:

    Identity 5 + Identity 6 结果是 11

    身份5 + 6. 结果是 11 再一次

    不管怎样,我试着用同样的方法 大概 像这样

    Just 5 + Just 6

    只有5个 + 6.

    我得到以下错误:

    <interactive>:2116:1: error:
        • Non type-variable argument in the constraint: Num (Maybe a)
          (Use FlexibleContexts to permit this)
        • When checking the inferred type
            it :: forall a. (Num (Maybe a), Num a) => Maybe a
    

    我试过了 FlexibleContexts 但我只是得到了以下错误:

    <interactive>:2134:1: error:
        • No instance for (Num (Maybe a0)) arising from a use of ‘it’
        • In the first argument of ‘print’, namely ‘it’
          In a stmt of an interactive GHCi command: print it
    

    我想知道是否有人能解释一下为什么 身份 单子的行为与单子不同 大概 ?

    也可以使用 灵活语境 用同样的方式 大概 蒙纳德?到目前为止,我还没能让它工作。

    1 回复  |  直到 5 年前
        1
  •  3
  •   David Young    8 年前

    这是因为 Identity 有一个 Num 实例和 Maybe 不(您可以使用 :i 在GHCi中还是在寻找 in the Hackage documentation ).

    所以,当你 \x -> Identity 2 >>= \y -> x * y 那个 * 实际上是 * 号码 例如 Identity a (在哪里 a 它本身就是一个 号码 比如说 Int Double 等等)。

    此外,Haskell中的数字文字是多态的: 5 :: Num a => a ,所以他们可以像任何人一样行事 号码 实例,而不是局限于特定的实例(如 智力 双重的 ).当你尝试这样的事情时就会发生这种情况 Identity 5 + 6 这个 6 被推断为具有类型 Num a => Identity a 自从 (+) :: Num a => a -> a -> a .

    你可以更明确地看到这一点:

    ghci> :t 5
    5 :: Num p => p
    ghci> 5 :: Identity Int
    Identity 5
    ghci> 5 :: Maybe Int
    
    <interactive>:12:1: error:
        • No instance for (Num (Maybe Int)) arising from the literal ‘5’
        • In the expression: 5 :: Maybe Int
          In an equation for ‘it’: it = 5 :: Maybe Int
    
    推荐文章