有这样一种情况:
有一个功能
fn :: Bool -> Bool -> Bool -> Bool。有一个由函数参数的可能值列表组成的列表
fn:([[False, False, False], ... , [True, True, True]]由函数参数的数量生成)
我想在Python中实现类似“星号表达式”的东西:fn(*[a,b,...,z]) == fn(a,b,...,z)
并做这样的事情来获取所有“参数”列表的函数值:map (t $ fn) [[False, False, False], [True, True, True]]where t f [x,y,z] = f x y z.
问题是参数fn可能不是三个,而是或多或少。As 分别是 和 "argument" 列表中的元素。
如何实现一个函数t,以便它将具有可变数量元素的列表作为第二个参数?提前致谢!
编辑:
我达到了理想的解决方案,似乎:foldl a (\x -> \y -> \z -> z) [1,2,3]在哪里a = \f -> \x -> f x。让我们做一个 beta 减少:
a (\x -> \y -> \z -> z) 1==(\x -> (\t -> \y -> \z -> z) x) 1==\y -> \z -> za (\y -> \z -> z) 2==(\x -> (\y -> \z -> z) x) 2==\z -> za (\z -> z) 3==(\x -> (\z -> z) x) 3==3
但:
• Occurs check: cannot construct the infinite type: t0 ~ t0 -> t0
Expected type: (t0 -> t0 -> t0 -> t0) -> t0 -> t0 -> t0 -> t0 -> t0
Actual type: (t0 -> t0 -> t0 -> t0 -> t0)
-> t0 -> t0 -> t0 -> t0 -> t0
• In the first argument of ‘foldl’, namely ‘a’
In the second argument of ‘($)’, namely
‘foldl a (\ x -> \ y -> \ z -> z) [1, 2, 3]’
In the second argument of ‘($)’, namely
‘show $ foldl a (\ x -> \ y -> \ z -> z) [1, 2, 3]’
查德特?
“橡胶”
curry当然可以。您的示例 cfoldl不起作用,因为每次迭代的结果必须是相同的类型,但您的类型不同:第一次迭代Bool -> Bool -> Bool,第二次Bool -> Bool,第三次Bool。但是 Haskell 有一种机制,允许您创建具有可变参数类型的函数。这种机制就是类。
这里
f, 是您要使用列表中的参数调用的函数类型,并且t是您的搜索函数。它的第一个参数是一个函数f,它的第二个参数是一个参数列表,它返回f使用这些参数调用的结果。第一种情况是基本的:一个空的参数列表。在这种情况下,函数类型
f简单地退化为Bool. 毕竟,没有参数的函数只是一个值。让我们写:请注意,如果您在此处传递非空列表,则会引发错误。我会回到这个。
第二种情况是递归的:一个由头和尾组成的参数列表。在这种情况下,函数的类型
f必须是Bool -> a,其中Bool是它的第一个参数,并且a是函数的“余数”,也就是说,一个函数需要除第一个参数之外的所有参数,然后返回一个值。让我们写:在这里,函数
t将第一个参数(列表的“头”)传递给函数f,该函数返回“函数的剩余部分”,然后将其t与其余部分一起传递给函数的“先前”版本参数(列表的“尾部”)。让我们检查一下它是如何工作的:
这种方法可以推广到任何类型,而不仅仅是
Bool. 该类及其实现将如下所示:唯一的区别是额外的变量
res,它存在于类和实现中,替换了类型Bool。但是,看看你的评论,我怀疑这正是你想要的。特别要注意,在我的实现中,如果
t使用“错误”数量的参数调用函数,则会引发错误。但是对于我在评论中关于在这种情况下应该发生什么的问题,您回答:这是不可理解的。例如,以下程序应该如何工作:
在我的实现中,它会在运行时抛出一个错误。你在期待什么?
假设你说这样的程序不应该编译。好的,然后让用户输入参数列表:
然后怎样呢?不清楚。
如果您指定您希望看到的确切内容,也许我可以提供更好的解决方案。