首页 > 解决方案 > 如何派生此函数的类型:

问题描述

我正在努力提高玩“俄罗斯方块”的能力。我有以下功能:

(=<<) :: Monad m => (a -> m b) -> m a -> m b
zip :: [a] -> [b] -> [(a, b)]

GHCI 告诉我:

(zip =<<) :: ([b] -> [a]) -> [b] -> [(a, b)]

我很难弄清楚如何从前两个中得出最终的签名。我的直觉(因为没有更好的词)是说 is 的第一个论点=<<a -> mb某种方式与 的签名相协调zip,然后它应该全部从那里掉出来。但我无法理解如何实现这一飞跃。它可以分解为一系列易于遵循的步骤吗?

标签: haskelltypescomposition

解决方案


(zip =<<)等价于(>>= zip),这可能使其更具可读性。正如您正确观察到的那样,无论哪种方式,都zip占据了这些功能中的位置。(a -> m b)

要进行的一种更直观的转换是考虑=<<. 它“接受”两个参数,所以如果我们将它应用于一个,我们应该只剩下一个。因此,签名([b] -> [a]) -> [b] -> [(a, b)]是一元函数!

(zip =<<) :: ([b] -> [a]) -> ([b] -> [(a, b)])
             ------------    -----------------
                 m a'                m b'

那是什么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)]

推荐阅读