Haskell中依赖入参的函数能否通过eta转换消去显式参数
完全可以实现你要的参数消去效果,但这不是只靠基础eta转换就能做到的:基础eta转换仅支持f x = g x等价为f = g这类单参数尾透传的化简,你的代码里有基于参数值的分支判断,需要搭配高阶组合子实现无点(point-free)风格,就能做到不在areaOrPerimeter的定义里显式写出x、y形参。
最容易理解的零依赖实现
不需要导入任何额外模块,抽一个通用的双参数分支组合子即可,运行逻辑和你原来的代码完全一致:
areaOrPerimeter :: Double -> Double -> Double areaOrPerimeter = branch (==) area perimeter where branch cond trueCase falseCase a b | cond a b = trueCase a b | otherwise = falseCase a b
这里areaOrPerimeter的定义行完全没有出现x、y参数,所有参数的接收、判断、透传逻辑都封装在branch这个通用组合子里,之后遇到类似的双参数分支场景你也可以复用这个组合子。
借助标准库的精简写法
如果允许导入标准库工具,还可以写得更短,用Data.Bool里的bool函数(语义和if一致,参数顺序为bool 假分支返回值 真分支返回值 判断条件)即可:
import Data.Bool (bool) areaOrPerimeter :: Double -> Double -> Double areaOrPerimeter x = bool (perimeter x) (area x) =<< (== x)
如果要连这里的x也消去,还可以继续用函数式组合子拼接,但写法会变得非常晦涩,实际开发中并不推荐——你原来写的带显式x、y的守卫写法可读性是最好的,没必要为了追求无点风格强行降低代码可维护性。
内容的提问来源于stack exchange,提问作者evlogii
相关产品推荐
相关产品推荐

