我对Haskell相对较新,如果我的问题听起来很愚蠢,那么道歉.我一直试图理解功能组合是如何工作的,我遇到了一个问题,我想知道有人可以帮助我.我在以下两个场景中使用函数组合中的map:
map (*2) . filter even [1,2,3,4]map (*2) . zipWith max [1,2] [4,5]虽然filter和zipWith函数都返回一个列表,但只有第一个组合有效,而第二个组合会抛出以下错误:
"Couldn't match expected type '[Int] -> [Int]' with actual type '[c0]'
Run Code Online (Sandbox Code Playgroud)
任何建议将不胜感激.
将列表压缩到自身的函数可以定义为:
let adjacent1 l = zip l $ tail l
Run Code Online (Sandbox Code Playgroud)
这有效,但我想以无点样式定义它.为此,我定义了一个函数dollarize:
let dollarize f1 f2 x = f1 x $ f2 x
let adjacent1 = dollarize zip tail
Run Code Online (Sandbox Code Playgroud)
这很有效,但显然我不想定义自己的高阶函数.有没有办法找到标准的等价物dollarize,假设它存在?如果没有,这种功能在哪里组合功能?
haskell functional-programming pointfree function-composition
所以,让我们直截了当.
:t (map.foldr)
(map.foldr) :: (a1 -> a -> a) -> [a] -> [[a1] -> a]
Run Code Online (Sandbox Code Playgroud)
什么是[[a1] - > a]?我真的想要理解这个构图,所以我这样做:
-- map.foldr
map.foldr :: (a1 -> a -> a) -> [a] -> [[a1] -> a]
map :: (a1 -> b1) -> [a1] -> [b1]
(.) :: (y -> w) -> (x -> y) -> x -> w
foldr :: (a -> b -> b) -> b -> [a] -> b
y = (a1 -> b1) w = ([a1] -> [b1]) …Run Code Online (Sandbox Code Playgroud) 对 Erlang 来说是全新的。我试图定义函数组合一些功能,比如compose,juxt和pipe而运行到一个事实,即二郎神没有(据我所知)可变参数所以这是很难写只是一个版本的这种功能,将所有输入工作.
到目前为止,我最好的想法是将不同数量的函数硬编码到一个合理的数字,并提供一个版本,该版本采用更大的列表,如下所示:
pipe (X, Fs) when is_list(Fs) -> lists:foldl(fun (F, Acc) -> F(Acc) end, X, Fs);
pipe (X, F) -> F(X).
pipe (X, F, G) -> G(F(X)).
pipe (X, F, G, H) -> H(G(F(X))).
pipe (X, F, G, H, I) -> I(H(G(F(X)))).
pipe (X, F, G, H, I, J) -> J(I(H(G(F(X))))).
pipe (X, F, G, H, I, J, K) -> K(J(I(H(G(F(X)))))).
pipe (X, F, G, H, I, J, K, L) -> L(K(J(I(H(G(F(X))))))). …Run Code Online (Sandbox Code Playgroud) 功能组合从右到左组成:
const comp = f => g => x => f(g(x));
const inc = x => x + 1;
const dec = x => x - 1;
const sqr = x => x * x;
let seq = comp(dec)(comp(sqr)(inc));
seq(2); // 8
Run Code Online (Sandbox Code Playgroud)
seq(2)转换为dec(sqr(inc(2)))和应用程序顺序inc(2)...sqr...dec.因此,函数按照传递给它们的相反顺序调用comp.这对于Javascript程序员来说并不直观,因为他们习惯于从左到右的方法链接:
o = {
x: 2,
inc() { return this.x + 1, this },
dec() { return this.x - 1, this },
sqr() { return this.x * this.x, this }
} …Run Code Online (Sandbox Code Playgroud) javascript functional-programming associative composition function-composition
我喜欢柯里化,但有几个 Javascript 开发人员拒绝这种技术的原因有几个:
f(x) (y) (z)有没有一种方法可以减轻这些担忧,这样我的同事就不会讨厌我?
javascript functional-programming currying function-composition higher-order-functions
在我们的代码中,我们创建了许多“ finagle管道”,如下所示:
val f1 = new Filter[A,B,C,D](...)
val f2 = new SimpleFilter[C,D](...)
val f3 = new Filter[C,D,E,F](...)
val s = new Service[E,F](...)
val pipeline: Service[A,B] = f1 andThen f2 andThen f3 andThen s
Run Code Online (Sandbox Code Playgroud)
我现在希望能够在这样的链中的任何地方 “插入”记录器。记录器只会记录请求进入并收到响应的事实。像这样:
class LoggerFilter[Req, Resp](customLog: String) extends SimpleFilter[Req, Resp] with LazyLogging{
override def apply(request: Req, service: Service[Req, Resp]): Future[Resp] = {
logger.info(s"$customLog => Request: ${request.getClass.getName} -> ${service.toString}")
service(request).map{resp =>
logger.info(s"$customLog => Response: ${resp.getClass.getName} -> ${request.getClass.getName}")
resp
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用这种方法,我们必须不断声明多个记录器,以便类型可以正确对齐,然后在“正确的位置”插入。
val logger1 = new LoggerFilter[A,B]("A->B Logger") …Run Code Online (Sandbox Code Playgroud) 我最近又在探索 TypeScript。它的关键限制之一似乎是无法键入函数组合。让我首先向您展示 JavaScript 代码。我正在尝试输入:
const getUserById = id => new Promise((resolve, reject) => id === 1
? resolve({ id, displayName: 'Jan' })
: reject('User not found.')
);
const getName = ({ displayName }) => displayName;
const countLetters = str => str.length;
const asyncIsEven = n => Promise.resolve(n % 2 === 0);
const asyncPipe = (...fns) => x => fns.reduce(async (y, f) => f(await y), x);
const userHasEvenName = asyncPipe(
getUserById,
getName,
countLetters,
asyncIsEven
);
userHasEvenName(1).then(console.log);
// ? false
userHasEvenName(2).catch(console.log);
// …Run Code Online (Sandbox Code Playgroud) asynchronous functional-programming function-composition promise typescript
我创建了一个将函数链接在一起的函数。我创建了一堆通用类型来正确关联结果函数可以具有的参数。您可以在此处阅读有关此范例的更多信息、我正在寻找的内容以及我创建它的原因。
一切正常……到了一定程度。由于我生成类型的方式,当链变得太长时,TypeScript 会失败。我正在寻找一种方法来缓解这个问题。
我收到此错误:
Type instantiation is excessively deep and possibly infinite.
毫无疑问,这对于 TypeScript 来说太多了,而且随着每个函数的添加,类型映射呈指数级增长。
我意识到这段代码相当复杂,所以我不是在寻找完整的技术解决方案,只是寻找一种更符合 TypeScript 的/算法更简单的方法来做同样的事情。
namespace Poly {
export type Omit<T, K extends string | number | symbol> = { [P in Exclude<keyof T, K>]: T[P]; }
}
namespace Use {
type ThenArg<T> = T extends Promise<infer U> ? U : T
type RelatedThen<A, B> = A extends Promise<infer U> ? Promise<B> : B
export type Func = (...args: any[]) => any
export type Return<A extends …Run Code Online (Sandbox Code Playgroud) composition infinite-loop control-flow function-composition typescript
我正在尝试创建一个由函数 f(x) 组成 N 次的函数,类似于:
function CompositionN(f,N)
for i in 1:N
f(x) = f(f(x))
end
return f(x)
Run Code Online (Sandbox Code Playgroud)
我需要函数 CompositionN 返回另一个函数,而不是值。
composition ×3
haskell ×3
javascript ×2
map ×2
typescript ×2
associative ×1
asynchronous ×1
control-flow ×1
currying ×1
erlang ×1
finagle ×1
fold ×1
julia ×1
mutable ×1
pointfree ×1
promise ×1
repeat ×1
scala ×1
syntax ×1