使用记录访问器定义应用程序的 <*> 时出错:无法构造无限类型:t ~ t -> t1



我有以下代码:

{-# LANGUAGE DeriveFunctor #-}
data Foo a = Foo { field1 :: a, field2 :: a} deriving (Functor)
instance Applicative Foo where
  pure a = Foo a a
  f <*> a = Foo (r field1) (r field2)
    where r g = g f $ g a

我在GHCI中遇到以下错误:

help.hs:8:23: error:
    • Occurs check: cannot construct the infinite type: t ~ t -> t1
    • In the second argument of ‘($)’, namely ‘g a’
      In the expression: g f $ g a
      In an equation for ‘r’: r g = g f $ g a
    • Relevant bindings include
        g :: Foo (a -> b) -> t -> t1 (bound at help.hs:8:13)
        r :: (Foo (a -> b) -> t -> t1) -> t1 (bound at help.hs:8:11)
help.hs:8:25: error:
    • Couldn't match type ‘a’ with ‘a -> b’
      ‘a’ is a rigid type variable bound by
        the type signature for:
          (<*>) :: forall a b. Foo (a -> b) -> Foo a -> Foo b
        at help.hs:7:5
      Expected type: Foo (a -> b)
        Actual type: Foo a
    • In the first argument of ‘g’, namely ‘a’
      In the second argument of ‘($)’, namely ‘g a’
      In the expression: g f $ g a
    • Relevant bindings include
        g :: Foo (a -> b) -> t -> t1 (bound at help.hs:8:13)
        r :: (Foo (a -> b) -> t -> t1) -> t1 (bound at help.hs:8:11)
        a :: Foo a (bound at help.hs:7:9)
        f :: Foo (a -> b) (bound at help.hs:7:3)
        (<*>) :: Foo (a -> b) -> Foo a -> Foo b (bound at help.hs:7:3)

如何实现此应用函数的FOO实例,以使其编译?

定义

r g = g f $ g a

要求g是多态性函数-GHC无法推断出如此复杂的类型。

如果您确实希望代码编译:

,则需要更加明确。
{-# LANGUAGE ScopedTypeVariables, DeriveFunctor, InstanceSigs, Rank2Types #-}
instance Applicative Foo where
  pure a = Foo a a
  (<*>) :: forall a b. Foo (a->b) -> Foo a -> Foo b
  f <*> a = Foo (r field1) (r field2)
     where
     r :: (forall t. Foo t -> t) ->  b
     r g = g f $ g a

另外,可以使用更直接的方法:

instance Applicative Foo where
  pure a = Foo a a
  (Foo f1 f2) <*> (Foo a1 a2) = Foo (f1 a1) (f2 a2)

最新更新