如何导出此函数的类型:

Cam*_*all 14 haskell types composition

我正试图在打"类型俄罗斯方块"方面做得更好.我有这些功能:

(=<<) :: Monad m => (a -> m b) -> m a -> m b
zip :: [a] -> [b] -> [(a, b)]
Run Code Online (Sandbox Code Playgroud)

而GHCi告诉我:

(zip =<<) :: ([b] -> [a]) -> [b] -> [(a, b)]
Run Code Online (Sandbox Code Playgroud)

我很难搞清楚如何从前两个签到最终签名.我的直觉(由于缺乏一个更好的词)是说的第一个参数=<<,即a -> mb以某种方式对和解的签名zip,然后将其都应该从脱落.但我无法理解如何实现这一飞跃.它可以分解为一系列易于遵循的步骤吗?

Bar*_*icz 8

(zip =<<)相当于(>>= zip),这使得它可能更具可读性.无论哪种方式,正如您正确观察到的那样,zip占据了(a -> m b)这些功能中的插槽.

另一个更直观的转变是思考=<<.它"需要"两个参数,因此如果我们将它应用于一个参数,我们应该只剩下一个参数.因此,签名([b] -> [a]) -> [b] -> [(a, b)]是一元函数!

(zip =<<) :: ([b] -> [a]) -> ([b] -> [(a, b)])
             ------------    -----------------
                 m a'                m b'
Run Code Online (Sandbox Code Playgroud)

那是什么m?Monad实例存在于函数(r ->)(或者,替代地(->) r).所以在这种情况下r :: [b](因而m :: ([b] ->)),a' :: [a]b' :: [(a, b)].

因此,zip正如我们在开头所断言的那样:

a'  -> m b'                    -- substitute [(a,b)] for b'
a'  -> m [(a, b)]              -- substitute [a] for a'
[a] -> m [(a, b)]              -- substitute ([b] ->) for m
[a] -> ([b] -> [(a,b)])

[a] -> [b] -> [(a,b)]
Run Code Online (Sandbox Code Playgroud)


n. *_* m. 7

在其他事情之前做两件事有助于:

  1. 把明确的括号x->y->z变成了x->(y->z)
  2. 重命名类型变量,以便没有冲突

考虑到这一点,让我们重写类型

(=<<) :: Monad m => (a -> m b) -> (m a -> m b)
zip :: [x] -> ([y] -> [(x, y)])
Run Code Online (Sandbox Code Playgroud)

现在匹配类型.第一个参数=<<zip,所以(a -> m b)是相同的[x] -> ([y] -> [(x, y)]).

a          ->        m b
[x]        ->        ([y] -> [(x, y)])
Run Code Online (Sandbox Code Playgroud)

所以,a[x]m b([y] -> [(x, y)]).重写->前缀表示法,我们得到-> [y] [(x, y)],这是相同的(-> [y]) [(x, y)].

m             b
(-> [y])      [(x, y)]
Run Code Online (Sandbox Code Playgroud)

m(-> [y])(确实是一个单子)而且b[(x, y)].

所以现在我们知道什么是什么a,什么是b什么,什么是什么m.让我们(m a -> m b)用这些术语重写:

(m            a)          ->          (m            b)
((-> [y])     [x])        ->          ((-> [y])     [(x, y)])
Run Code Online (Sandbox Code Playgroud)

我们再次以中缀风格重写

([y] -> [x])              ->          ([y] -> [(x, y)])
Run Code Online (Sandbox Code Playgroud)

这就是变量名称,是GHC给你的答案.