Haskell 中“join bimap”的签名

Kar*_*her 1 haskell type-inference parametric-polymorphism

在 codewars 的解决方案之一中,我遇到了以下表达式:

join bimap
Run Code Online (Sandbox Code Playgroud)

其中join :: Monad m => m (m a) -> m a, 和 bimap :: Bifunctor p => (a -> b) -> (c -> d) -> p a c -> p b d. 生成的表达式的类型为:Bifunctor p => (c -> d) -> p c c -> p d d

我可以猜测 的类型bimap可以写成 形式 (->) (a->b) ((->) (c->d) p a c -> p b d),但我不知道如何p a c转向p c cp b dto p d d。请给我一些如何解开这个谜题的提示。

bra*_*drn 5

join首先,让\xe2\x80\x99s 看看应用于函数的 as 类型。让\xe2\x80\x99s 说你有一个函数f :: t -> u -> v;或者,等效地,f :: (->) t ((->) u v). 我们可以尝试join :: Monad m => m (m a) -> m a通过比较这两种类型来统一这一点:

\n
           (->) t ((->) u v)\nMonad m => m      (m      a) -> m a\n
Run Code Online (Sandbox Code Playgroud)\n

m ~ (->) t因此,我们可以尝试通过设置和来统一类型a ~ v

\n
(->) t ((->) u v)\n(->) t ((->) t v) -> (->) t v\n
Run Code Online (Sandbox Code Playgroud)\n

但有一个问题:我们还需t ~ u要让这些类型匹配!因此我们可以得出结论,join只有当前两个参数具有相同类型 \xe2\x80\x94 时,才能应用于函数,如果不是,则只有在有join办法使它们相等的情况下,我们才能应用于该函数。

\n

现在,想一想bimap :: Bifunctor p => (a -> b) -> (c -> d) -> p a c -> p b d。通常,abcdp可以是任何类型。但如果您想应用于joinbimap这会增加一个约束,即 的前两个参数bimap必须具有相同的类型:即(a -> b) ~ (c -> d)。由此我们可以得出结论a ~ cb ~ d。但是,当然,这意味着p a c必须与p a ap b d相同p b b,才能解决难题。

\n