【问题标题】:Compose functions at runtime based on user input in Haskell基于 Haskell 中的用户输入在运行时编写函数
【发布时间】:2011-07-27 14:24:10
【问题描述】:

假设我有 100 个各种简单签名的函数(从单态开始,但也想让多态案例工作)a -> b (Int -> Int, Int -> String, String -> Double, MyType -> MyOtherType 等)

假设我向用户显示了这些列表。用户选择一个。我显示了一个函数列表,其参数与所选函数的输出兼容。用户选择一个。

我现在如何组合这两个函数?一般情况是一系列组合,但我认为这个简单的情况涵盖了我正在处理的问题。

我知道我可以尝试 unsafeCoerce 或 Data.Dynamic,但我想看看我是否可以避免这种情况,而且这些显然仅限于导致问题的单态类型。

我想也许我可以以某种方式创建所有函数的数据结构以及它们可以组合的内容,但我不确定。而当包括多态情况时,似乎是不可能的。

【问题讨论】:

  • 你的函数从何而来?在你的程序中硬编码?在配置文件中以源代码形式提供?介于两者之间?

标签: haskell


【解决方案1】:

问题归结为:我如何向编译器证明 这个输入那个函数 以及我对 那个函数的输出做了什么 都以合理的方式排队?有几个答案。

  • 告诉编译器“相信我”。使用unsafeCoerce
  • 告诉编译器“我有点猜测,但我很确定我是对的——所以请检查我,但在运行时,而不是在编译时。”。使用Data.Dynamic
  • 对函数的a -> b 类型中的ab 类型进行案例分析证明。取决于ab 有多少选择,这可能有点麻烦。
  • 承认您正在为自己的小语言编写解释器和类型检查器,并正确执行。创建一个语法,编写一个小解析器,创建一个 AST,进行类型检查和评估。 GADT 可以帮助您利用 GHC 的类型检查器,减少您必须执行的类型检查量(但偶尔会增加您必须执行的键盘输入量)。

作为第三个选项的示例,假设您有 f :: Int -> Stringg :: Double -> Boolchoice1 :: Intchoice2 :: Intchoice3 :: Intchoice4 :: Double。你可以这样写:

main = prompt "f or g" >>= \ans -> case ans of
    "f" -> prompt "1, 2, or 3" >>= \ans -> case ans of
        "1" -> doSomethingWithString (f choice1)
        "2" -> doSomethingWithString (f choice2)
        "3" -> doSomethingWithString (f choice3)
    "g" -> prompt "4 is your only choice" >>= \ans -> case ans of
        "4" -> doSomethingWithBool (g choice4)

这种方法通常可以清理很多 - 例如,所有“f”案例都可以折叠。

【讨论】:

【解决方案2】:

我不确定您打算在创建组合函数后如何处理它,因为它的参数和结果将具有未知类型。我想你可以继续对它应用参数,直到它不再是一个函数,但是你将无法对结果做任何有用的事情,除非你将它限制为某个类的成员(如Show)。

为什么要避开Data.Dynamic?这似乎是一个固有的动态问题。为了能够匹配兼容的函数,您需要一种将类型表示为数据的方法,因此Data.Typeable 似乎很合适。

这听起来像是你想在运行时做 Haskell 编译器在编译时做的事情。也许您可以动态地构建代码并使用System.Eval.Haskell 即时评估它。

【讨论】:

  • 最终,组合可能会评估为 IO () 或其他东西。 Data.Dynamic 似乎仅限于单态,因此不起作用。我来看看 System.Eval.Haskell。
猜你喜欢
  • 1970-01-01
  • 2013-10-16
  • 2010-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-03
  • 2020-04-07
  • 1970-01-01
相关资源
最近更新 更多