无点包装围绕=<<

时间:2016-02-26 23:07:49

标签: haskell

假设我在GHCi 7.6.3中定义了一个函数

> let fstM xs = ((=<<) (return . fst)) xs
> :t fstM
fstM :: Monad m => m (b, b1) -> m b
> fstM [(1,2), (3,4)]
[1,3]
> fstM (Just (1,2))
Just 1

这不是一个令人兴奋的功能;它基本上只是liftM fst。但是,如果我尝试以无点样式定义它,我会收到以下错误:

> let fstM = ((=<<) (return . fst))

<interactive>:8:13:
    No instance for (Monad m0) arising from a use of `=<<'
    The type variable `m0' is ambiguous
    Possible fix: add a type signature that fixes these type variable(s)
    Note: there are several potential instances:
      instance Monad ((->) r) -- Defined in `GHC.Base'
      instance Monad IO -- Defined in `GHC.Base'
      instance Monad [] -- Defined in `GHC.Base'
      ...plus two others
    In the expression: ((=<<) (return . fst))
    In an equation for `fstM': fstM = ((=<<) (return . fst))

表达本身似乎很好

> :t ((=<<) (return . fst))
((=<<) (return . fst)) :: Monad m => m (b, b1) -> m b

但试图给它命名失败。

显然我的理解存在差距;我不知道第一个定义如何推断出类型约束,而第二个定义则表明它是模棱两可的。也就是说,我知道我可以写

fstM :: Monad m => m (a, b) -> m a
fstM = ((=<<) (return . fst))

解决歧义,但是看似不必要的参数使得类型声明变得不必要有什么特别的呢?

0 个答案:

没有答案