【问题标题】:haskell Function taking 2 arguments returns function which takes one argument?haskell 带 2 个参数的函数返回带一个参数的函数?
【发布时间】:2013-10-27 03:31:23
【问题描述】:

考虑这段代码:

type Graph = (Char, Function) 
type Function = Char -> Int 
doThingsWithGraph :: Graph -> String
func :: Function 
graph :: Graph

main = do  x <- getChar
           y <- getChar
           let graph = (x, func)
           putStrLn $ doThingsWithGraph graph

doThingsWithGraph 的实现暂时无关紧要。现在这里的问题是func 的输出也取决于我从用户那里得到的第二个字符,但我不知道如何将它传递给它。我不能将它作为参数传递,因为 func 是由第三方实现的,我无法更改类型。因此,如果 haskell 具有全局变量并且 y 是其中之一,那么 func 的实现将如下所示:

func char 
       |isDigit char = digitToInt char + digitToInt y
       |otherwise    = digitToInt y

这显然行不通,因为func 不知道y 是什么,但这就是它应该做什么的想法。所以y 是我需要以某种方式让func 知道的值(这是我在main 第二行从用户那里得到的值)。我不能在func 内做getLine,因为这与我无法更改的数据类型(大型框架的一部分)不一致。有任何想法吗?也许一些辅助函数可以替换let graph = (x, func)中的func,然后返回函数类型的函数?这只是一个猜测..

【问题讨论】:

  • 我不太确定“func 由第三方实施”是什么意思。你的意思是“我希望第三方能够实现这样的funcs”吗?
  • 对不起,我误导了,我的意思是“图形”已经在我正在使用的框架中实现,并且需要一个 Function 类型的函数作为第二个参数。

标签: haskell


【解决方案1】:

生成func 的用户可以简单地实现类似Char -&gt; Function 的函数并将其交给您,而不是原始的Function,并承诺您将输入中的第二个字符作为第一个参数提供给他们。

确实,在没有全局变量的语言中,这是一件非常自然的事情:您必须在函数输入中声明所需的所有信息。其他任何东西都行不通。

你最终会得到

doThingsWithGraph (x, makeFunc y)

当这变得繁重时,Reader Monad 可以提供帮助。

【讨论】:

  • 所以你是说我可以创建一个函数,它接受一个参数并返回一个接受其他参数的函数?如果是这样的话,那就是我需要的。我以前从未编写过返回函数的函数。你有任何进一步的提示如何实现这一点吗?谢谢!
  • 没错。 makeFunc 将是 Char -&gt; Char -&gt; Int 类型,这意味着您可以传递两个 Char 参数并获得一个 Int 或只传递一个参数并获得一个 Char -&gt; Int 函数。不需要额外的步骤。
  • @user2922609 完全正确! Haskell 中一个非常常见的模式。一开始很奇怪,毫无疑问,但您可以将所有多参数函数视为“一次应用一个参数”。例如,如果我们有add x y = x + y,那么add :: Int -&gt; Int -&gt; Intadd 2 :: Int -&gt; Int 都是完全有效的函数。此属性称为“部分应用程序”。
  • 另见haskell.org/haskellwiki/Currying,它解释了更多关于“函数返回函数”的技术。
【解决方案2】:

我不太确定“func 由第三方实施”是什么意思。你的意思是“我希望第三方能够以允许我这样使用它们的方式实现这样的funcs”吗?

如果是这样的话

func :: Char -> Function
func y char 
       |isDigit char = digitToInt char + digitToInt y
       |otherwise    = digitToInt y

做这份工作?我认为这也是 J. Abrahamson 的建议。

【讨论】:

    猜你喜欢
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 2023-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多