根据Haskell中的用户输入在运行时编写函数

时间:2011-07-27 14:24:11

标签: haskell

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

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

我现在如何撰写这两个功能?一般情况是一系列的组合,但我认为这个简单的案例涵盖了我正在使用的问题。

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

我想也许某种程度上我可以创建所有函数的数据结构以及它们可以组成的内容,但我不确定。当包含多态案例时,似乎不可能。

2 个答案:

答案 0 :(得分:12)

问题归结为:我如何向编译器证明此输入该函数以及我正在使用执行该函数的输出所有人都以明智的方式排队?有几个答案。

  • 告诉编译器“只相信我”。使用unsafeCoerce
  • 告诉编译器“我有点猜测,但我很确定我是对的 - 所以请检查我,但是在运行时,而不是在编译时。”使用Data.Dynamic
  • 对您的函数a类型中的ba -> b类型进行案例分析。根据{{​​1}}和a的选择数量,这可能会有点拖累。
  • 承认你正在为自己的小语言写一个翻译和打字检查器,并且做得很好。创建一个语法,编写一个小解析器,创建一个AST,进行类型检查和评估。 GADT可以帮助您利用GHC的类型检查器,减少您必须执行的类型检查的数量(但偶尔会增加您必须执行的键盘输入量)。

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

choice4 :: Double

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

答案 1 :(得分:1)

我不确定你创建的函数一旦创建后你打算做什么,因为它的参数和结果将是未知类型。我猜你可以继续向它应用参数,直到它不再是一个函数,但你不能对结果做任何有用的事情,除非你把它限制为某个类的成员(比如Show )。

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

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