function - haskell 风格的广义函数组合
问题描述
我们有一些不同的类型
Prelude> type T1 = Int
Prelude> type T2 = Int
Prelude> type T3 = Int
Prelude> type T4 = Int
...
Prelude> type X1 = Int
Prelude> type X2 = Int
Prelude> type X3 = Int
Prelude> type X4 = Int
和一些功能
Prelude> let f1 :: X1->T1; f1 = (+1)
Prelude> let f2 :: X2->T2; f2 = (+2)
Prelude> let f3 :: X3->T3; f3 = (+3)
...
let g :: T1 -> T2 -> T3; g = (+)
我想构建一些新功能,例如:
c :: X1 -> X2 -> T3
c x1 x2 = g (f1 x1) (f2 x2)
但是如果我想定义新函数更像是组合方式而不显式使用参数怎么办
Prelude> nc = flip ((flip (g.f1)).f2)
现在 nc 作为 c
但是使用翻转我只能对 N=2 个参数执行此操作,我为 N=3 堆叠:
Prelude> let g3 :: T1->T2->T3->T4; g3 t1 t2 t3 = t1+t2+t3
Prelude> :t (flip ((flip (g3.f1)).f2))
(flip ((flip (g3.f1)).f2)) :: X1 -> X2 -> T3 -> T4
Prelude> :t flip (flip ((flip (g3.f1)).f2))
flip (flip ((flip (g3.f1)).f2)) :: X2 -> X1 -> T3 -> T4
怎么先做T3?并且随着 N 的增长,它变得复杂且不可读。
我想将这个想法推广到任意 N 函数。
所以我认为我需要一些函数来输入所有这些东西并产生组合函数
最后我提出了为所有 N 定义合成器函数的解决方案:
Prelude> compose3 = \g f1 f2 f3 x1 x2 x3 -> g (f1 x1) (f2 x2) (f3 x3)
Prelude> compose4 = \g f1 f2 f3 f4 x1 x2 x3 x4 -> g (f1 x1) (f2 x2) (f3 x3) (f4 x4)
... etc
let c3 = compose3 g3 f1 f2 f3
Prelude> :t c3
c3 :: X1 -> X2 -> X3 -> T4
Prelude> c3 1 2 3
12
但它需要为每个 N 编写定义
为 abitary N 做这样的组合的表达方式是什么?
我知道有一个用于特定功能组合的 Reader monad,但是我搜索具有不同类型输入的通用,Monads 可以完成这项工作吗?
另外我对Arrow typeclass知之甚少,可能在这里适用吗?如果是,请您提供示例。
解决方案
推荐阅读
- sql - Oracle Join Using + 派生列
- sql-server - 从原始列中获取值
- wso2 - 删除 Wso2 中的 SSO Saml 响应重定向页面?
- firebase - 实时数据库 Firebase “全有或全无”事务
- data-binding - 使用 ReactiveUI 将 ReactiveList 绑定到 Xamarin.Android 中的微调器的正确方法是什么
- angular - npm 错误!可以在以下位置找到此运行的完整日志:
- c# - 将datagrid columnheadertext绑定到集合
- java - git 命令转换为 jgit 命令
- java - 原子变量与同步方法
- android - kotlin android 片段 startActivity 和上下文