我收到一个警告,要求减少以下lambda表达式.
\(DataType arg1 arg2) -> DataType (modify arg1) arg2
Run Code Online (Sandbox Code Playgroud)
互联网告诉我eta-reducing意味着省去不必要的lambda.
map (\x -> fun x) list
map fun list
Run Code Online (Sandbox Code Playgroud)
这怎么适用于上面的代码?我可能只是缺少修改数据类型的基本语法?
对于这种情况,你不能再进一步减少它.lambda只有一个参数,即(DataType arg1 arg2).这些不是单独的参数,如括号所示,而是在构造函数上进行模式匹配.实际上,编译器会将此表达式减少为更类似的表达式
\arg -> case arg of
DataType arg1 arg2 -> DataType (modify arg1) arg2
Run Code Online (Sandbox Code Playgroud)
这里更清楚的是,lambda只有一个参数,并且它没有以可以减少它的方式使用.减少的主要规则是你有类似的东西
\a b c -> f b a c
Run Code Online (Sandbox Code Playgroud)
该c参数显示为参数声明和表达式中的最后一项,因此它可以被丢弃:
\a b -> f b a
Run Code Online (Sandbox Code Playgroud)
现在,如果我们想减少这个lambda,我们可以定义一个更高阶的函数
flip f a b = f b a
Run Code Online (Sandbox Code Playgroud)
并简单地写出来
flip f
Run Code Online (Sandbox Code Playgroud)
(注意flip已经存在Prelude).
您可以应用的另一个规则是与$经营者打交道时.简而言之,如果你有类似的东西
\a b c -> f a $ g b $ h c
Run Code Online (Sandbox Code Playgroud)
然后你可以先把它变成一个组合:
\a b c -> (f a . g b . h) c
Run Code Online (Sandbox Code Playgroud)
现在放弃这个c论点很简单
\a b -> f a . g b . h
Run Code Online (Sandbox Code Playgroud)
通常,您通常可以将$s 换成.s并删除最后一个参数.
同样,这不适用于您的情况,因为您的函数只有1个参数,并且该参数是模式匹配的,以提取构造函数的参数,然后从中重构一个全新的值.