假设我有100个不同简单签名的函数(从单态开始,但也希望多态情况也能工作)a -> b ( Int,Int -> String,String -> Double,MyType -> MyOtherType等)。
假设我向用户显示了这些内容的列表。用户选择一个。我显示了一个函数列表,这些函数的参数与所选函数的输出兼容。用户选择一个。
现在我该如何组合这两个函数呢?一般的情况是一系列的组合,但我认为这个简单的情况涵盖了我正在处理的问题。
我知道我可以尝试unsafeCoerce或Data.Dynamic,但我正在尝试是否可以避免这一点,而且这些显然限制在单态类型上,这会导致问题。
我想也许我可以创建一个所有函数的数据结构,以及它们可以组成什么,但我不确定这一点。当包含多态情况时,这似乎是不可能的。
发布于 2011-07-28 00:23:14
问题可以归结为:我如何向编译器证明这个输入和那个函数,以及我正在对该函数的输出做什么,都以一种合理的方式排列在一起?这里有几个答案。
unsafeCoerce.a -> b类型中的a和b类型上使用Data.Dynamic.a和b有多少选择,这可能有点拖后腿。创建一个语法,编写一个小解析器,创建一个AST,执行类型检查,并进行计算。GADT可以帮助您利用GHC的类型检查器,减少您必须进行的类型检查的数量(但有时会增加您必须进行的键盘输入的数量)。作为第三个选项的示例,假设您有f :: Int -> String、g :: Double -> Bool、choice1 :: Int、choice2 :: Int、choice3 :: Int和choice4 :: 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“情况都可以折叠。
发布于 2011-07-27 22:56:55
我不确定一旦组合函数被创建,你打算如何处理它,因为它的参数和结果将具有未知的类型。我猜你可以一直向它应用参数,直到它不再是一个函数,但是你不能对结果做任何有用的事情,除非你把它限制为某个类的成员(比如Show)。
为什么要避免使用Data.Dynamic?这似乎是一个内在的动态问题。为了能够匹配兼容的函数,您需要一种将类型表示为数据的方法,因此Data.Typeable似乎是合适的。
这听起来像是你想在运行时做Haskell编译器在编译时做的事情。也许您可以使用System.Eval.Haskell动态构造代码并对其进行动态评估。
https://stackoverflow.com/questions/6846027
复制相似问题