【发布时间】:2021-12-12 07:30:52
【问题描述】:
我是 Haskell 的新手,并试图不本能地思考命令。我有一个函数可以在模式匹配块中完成所有工作,但是它需要在参数上进行模式匹配在一个函数应用于它之后。
以一种功能性的方式这样做让我明白了这一点:
foo :: Int -> String
foo n = bar $ show n
bar :: String -> String
bar [] = ""
bar (c:s) = "-" ++ bar s
foo 是我要实现的功能,而bar 是完成所有工作的地方。 foo 的存在只是为了提供正确的类型签名并在调用 bar 之前执行前驱 show 转换。在实践中,bar 可能会变得相当复杂,但我仍然没有理由将它作为一个单独的函数公开。
Haskell 执行show 之类的简单函数并对其结果进行“then”模式匹配的方法是什么?
我尝试将模式匹配更改为case 语句,但它不允许最重要的递归,因为没有函数可以递归调用。出于同样的原因,使用where clause applied to multiple patterns 也不起作用。
【问题讨论】:
-
请注意,这是一个组合示例,因为
foo可以简单地定义为foo = bar . show。 -
把事情分解成多个功能是完全正常的;即使在命令式编程中,通常也建议保持程序/方法很小,将复杂的功能分解为多个单元。就像在大多数命令式语言中一样,您不必公开您编写的所有函数;模块系统完全能够导出
foo并保持bar私有。但是,您使用where找到的答案是一种很好的方式,可以完全清楚地表明bar仅用于定义foo,与任何其他目的无关。 -
惯用的方法是
foo n = '-' <$ show n——即尽可能重用现有的递归函数,而不是自己编写递归。 -
我可能是误会了,但你就不能
foo n = case (show n) of...吗? -
@RobinZigmond 差不多,但是当您执行
(c:s)案例时,没有bar可以递归调用。如果您尝试改为调用foo,您将传递一个String,它期待一个Int。
标签: haskell functional-programming