导出Haskell类型和(<*>)(<*>)的实现

gat*_*tek 7 haskell types functional-programming

我是一个刚开始学习Haskell的菜鸟,所以如果我问愚蠢的问题,请耐心等待.

最近我遇到了SO中的问题,演示了如何推导出函数和表达式的类型和实现(问题如

我怎么能理解"(.).(.)"?

&

Haskell函数组成,(.)(.)的类型以及它是如何呈现的 )

我发现答案非常鼓舞人心

然后,我尝试为自己做一些练习,以确保我知道如何应用这些技巧.

然后我自己想出这个表达:(<*>)(<*>)我不知道如何解决.

在GHCi中,它给出了类型签名:

(<*>)(<*>) :: Applicative f => (f (a -> b) -> f a) -> f (a -> b) -> f b
Run Code Online (Sandbox Code Playgroud)

但我的问题是我怎么能从这开始

(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)

并导出GHCi给出的类型签名?

而且,基于类型签名,如何实现(<*>)(<*>) = ??呢?

我陷入困境,无法通过重新安排术语等技术来解决这个问题.我甚至都不知道从哪里开始.

有人会帮我一个忙吗?

非常感谢

注意**:表达式(<*>)(<*>)确实没有特殊意义,这只是我随机为自己做的一个练习

Cac*_*tus 8

首先,让我们写出(<*>)两个不相交的类型变量集的类型:

(<*>) :: (Applicative f) => f (a -> b) -> f a -> f b
(<*>) :: (Applicative g) => g (c -> d) -> g c -> g d
Run Code Online (Sandbox Code Playgroud)

如果我们想要使用第二个作为其参数的第二个,我们需要

g (c -> d) ~ f (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)

生产

g ~ (f (a -> b) ->)    or,   ((->) (f (a -> b)) )
c ~ f a
d ~ f b
Run Code Online (Sandbox Code Playgroud)

并注意到选择g确实是一个适用的仿函数:它是非新颖的Reader (f (a -> b))应用程序.

所以应用程序有类型

g c -> g d
Run Code Online (Sandbox Code Playgroud)

我们现在知道的是

(f (a -> b) -> f a) -> (f (a -> b) -> f b)
Run Code Online (Sandbox Code Playgroud)

QED