为具有两个相同类型类的自定义数据类型实现applicative functor

Pan*_*der 3 haskell functor applicative

我试图让Twice成为applicative的成员,但是我在functor实现中得到了"a'的定义冲突":我也不确定如何正确实现<*>:/

data Twice a = Twice a a deriving (Show)

instance Functor Twice where
    fmap f (Twice a a) = Twice (f a) (f a)

instance Applicative Twice where
    pure x = (Twice x) x
    Twice f f <*> Twice x x = Twice ((f x) (f x))
Run Code Online (Sandbox Code Playgroud)

Wil*_*sem 6

我猜错误比语义更复杂.在你的定义中:

Twice f f <*> Twice x x = Twice ((f x) (f x))
Run Code Online (Sandbox Code Playgroud)

同样在Functor定义中:

fmap f (Twice a a) = Twice (f a) (f a)
Run Code Online (Sandbox Code Playgroud)

你在头上写了两个f和两个x.Haskell不允许这样做(Prolog确实如此,但即便如此,它可能不是你的意思).

在你写的身体里:

((f x) (f x))
Run Code Online (Sandbox Code Playgroud)

这意味着你将使用f x函数和f x参数进行函数调用,这也许可能不是你想要的.

我们可以在语法上修复它:

instance Functor Twice where
    fmap f (Twice a b) = Twice (f a) (f b)

instance Applicative Twice where
    pure x = Twice x x
    Twice f g <*> Twice x y = Twice (f x) (g y)
Run Code Online (Sandbox Code Playgroud)

请注意,您仍然需要证明这是有效的Functor,并Applicative通过采取记录这些类型类考虑约束实例.