Haskell中如何在执行模式匹配前对参数应用函数?
方案1:where子句定义内部私有辅助函数(首选)
这是最符合Haskell编码规范、可读性最高的实现方式,where块中定义的函数仅在当前函数作用域内可见,不会对外暴露,同时完全支持递归调用:
foo :: Int -> String foo n = bar $ show n where bar :: String -> String bar [] = "" bar (c:s) = "-" ++ bar s
你之前提到where子句无法满足需求,大概率是误解了where块的作用规则:where块中绑定的函数可以正常调用自身实现递归,完全可以替代顶层定义的辅助函数。
方案2:使用fix组合子实现匿名递归
如果你不想给辅助函数单独命名,可以使用Data.Function模块提供的fix组合子实现匿名递归,搭配case语句完成模式匹配:
import Data.Function (fix) foo :: Int -> String foo n = fix (\rec s -> case s of [] -> "" (_:rest) -> "-" ++ rec rest) $ show n
fix的作用是将传入函数的返回值作为该函数的第一个参数注入,上述代码中的rec就是递归调用的入口,不需要额外定义独立函数。
方案3:LambdaCase扩展简化写法
开启LambdaCase语法扩展后可以进一步简化case语句的写法:
{-# LANGUAGE LambdaCase #-} import Data.Function (fix) foo :: Int -> String foo n = fix (\rec -> \case [] -> "" (_:rest) -> "-" ++ rec rest) $ show n
内容的提问来源于stack exchange,提问作者Heath Raftery
相关产品推荐
相关产品推荐

