使用`MyApplicative((,)e)`中的`apply`

时间:2015-05-04 01:24:23

标签: haskell

鉴于以下内容,取自Typeclassopedia

class MyApplicative f where
    pure :: a          -> f a
    ap   :: f (a -> b) -> f a -> f b

instance Monoid e => MyApplicative ((,) e) where
  pure x             = (mempty, x)
  (u, f) `ap` (v, x) = (u `mappend` v, f x)

我尝试做类似的事情:

ghci> (+) <$> Control.Applicative.pure 100 <*> Control.Applicative.pure 50
150

但是,使用新定义的Applicative

ghci> Main.pure (+ 100) `ap` (Main.pure 50)

<interactive>:132:1:
    No instance for (MyApplicative f0) arising from a use of `it'
    The type variable `f0' is ambiguous
    Note: there is a potential instance available:
      instance Monoid e => MyApplicative ((,) e)
        -- Defined at MonoidWork.hs:8:10
    In the first argument of `print', namely `it'
    In a stmt of an interactive GHCi command: print it

查看类型:

ghci> :t Main.pure (+ 100)
Main.pure (+ 100) :: (MyApplicative f, Num a) => f (a -> a)

ghci> :t (Main.pure 50)
(Main.pure 50) :: (MyApplicative f, Num a) => f a

我不明白如何解决编译时错误。

1 个答案:

答案 0 :(得分:5)

你只需要给它一个类型签名。 GHC / GHCi有一些特殊的规则来默认某些类型类型的帮助,特别是当你在GHCi中时。否则,您必须始终执行1 + 2 :: Int之类的操作,而不仅仅是1 + 2。如果你给它一个类型签名,它就可以正常工作:

> Main.pure (+ 100) `ap` Main.pure 50 :: ((), Int)
((), 150)

GHC对你自己定义的类型类没有默认规则(并允许这样的行为很难做到正确,否则你的程序会产生意想不到的结果)。