haskell - Haskell中`join bimap`的签名
问题描述
在 codewars 的一个解决方案中,我遇到了以下表达式:
join bimap
哪里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 c
和。请给我一些提示如何解开这个难题。p b d
p d d
解决方案
首先,让我们看一下join
应用于函数的类型。假设你有一个函数f :: t -> u -> v
;或者,等价地,f :: (->) t ((->) u v)
。我们可以尝试join :: Monad m => m (m a) -> m a
通过比较两种类型来统一这一点:
(->) t ((->) u v)
Monad m => m (m a) -> m a
因此,我们可以尝试通过设置m ~ (->) t
和来统一类型a ~ v
:
(->) t ((->) u v)
(->) t ((->) t v) -> (->) t v
但是有一个问题:我们还需要t ~ u
这些类型匹配!因此我们可以得出结论,join
只有当前两个参数具有相同类型时才能应用于函数——如果它们不是,我们只能join
在有办法使它们相等的情况下应用于该函数。
现在,想想bimap :: Bifunctor p => (a -> b) -> (c -> d) -> p a c -> p b d
。通常,、 、a
和b
可以是任何类型。但是如果你想应用于,这会增加前两个参数必须具有相同类型的约束:即。由此我们可以得出结论和。但是,当然,这意味着必须与 相同,并且与 相同,解决难题。c
d
p
join
bimap
bimap
(a -> b) ~ (c -> d)
a ~ c
b ~ d
p a c
p a a
p b d
p b b
推荐阅读
- excel - VBA:过滤和排序预先存在的自动过滤器范围
- ruby - Ruby Gems 开发中的分享
- dart - StreamBuilder 限制
- firebase - 使用 facebook 登录在 null firebase auth 上调用 getter 'token' - Flutter
- c# - Unity3D 项目配置:将警告视为错误
- kubernetes - kubernetes 服务无法向自身发送请求
- scala - 根据 A 成员将 List[A] 转换为 List[Option[A]]
- swift - 将 `[URLQueryItem]` 缩减为 `[String: Any]`
- android - 将依赖项添加到 pubspec.yml 后,Flutter 应用程序无法在 android 中编译
- python-3.x - Python Pandas 映射一列但在出现异常时写入另一列