如何编写一个将可变参数函数作为参数的Haskell函数 [英] How to write a Haskell function that takes a variadic function as an argument
问题描述
我试图创建一个函数来获取可变参数作为参数,即
func ::(a - > ... - > a) - > a
我该如何做到这一点?
我已阅读了多元函数,我相信奥列格已经做到了,但是我失去了尝试在功能上应用模式以可变参数作为参数。特别是Olegs的方法似乎只适用于格拉斯哥扩展,我希望解决方案在纯Haskell 98中工作(如 Text.Printf )。
我问的原因是我试图建立一个函数,它将一个布尔函数作为参数,并检查它是否是一种重言式,即
isTautology ::(Bool - > ... - > Bool) - > Bool
可以输入:
isTautology(\ x - > x&& amp; not x)
isTautology(\ xy - > x&& y || not y)
我的问题是,我一直在阅读关于诀窍是将返回类型设置为类型变量它可以是结果或其他函数),但是我的返回类型是固定的(Bool)。 解决方案
您将为其定义函数实例的类型类,以及返回类型的实例。它是一个 Bool
这个事实根本不是问题。
我们正在尝试编写一个函数,它接受一个可变参数并返回一个 Bool
,所以我们将定义一个带有这样一个函数的类型类。
class Stmt a where
tautology :: a - > Bool
接下来,我们为可变参数函数的返回类型定义一个实例。在这种情况下,这是 Bool
。
- Bool是重言式,如果它是真的。
实例stmt bool其中
tautology = id
关键部分是下一个函数的实例需要一个 Bool
参数,并且其返回类型是我们类中的某种类型。这样,如果一个函数接受多个参数,这个实例将被多次应用。
- 一个函数是一个重复式总是返回重言式。
实例stmt b => Stmt(Bool - > b)其中
重言式f =重言式(f真)&&重言式(f False)
这样写需要 我们完成了。让我们试试看: I'm trying to create a function that gets a variadic function as an argument, i.e. how can I accomplish this? I've read about polyvariadic functions and I'm sure that Oleg already did it, however I'm lost trying to apply the pattern on a function with a variadic function as an argument. Especially Olegs approach seems to work with glasgow extensions only and I want the solution to work in pure Haskell 98 (like Text.Printf does). The reason that I ask is that I'm trying to build a function which takes a boolean function as an argument and checks whether it is a tautology, i.e. so that one could type: My problem is that I keep reading about the trick was to make the return type a type variable (so that it can be the result or another function), but my return type is fixed (Bool). The trick is to make a type class for which you will define an instance for functions, and an instance for the return type. The fact that it's a We're trying to write a function which takes a variadic argument and returns a Next, we define an instance for the return type of the variadic function. In this case, that's The key part is the next instance for functions that take a Writing it this way requires And we're done. Let's try it out:
这篇关于如何编写一个将可变参数函数作为参数的Haskell函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! FlexibleInstances
因为第二个实例头中的 Bool
。要用纯粹的Haskell 98做同样的事情,我们需要使用适当约束的类型变量。例如,我们可以使用 Bounded
和 Enum
(对于 Bool < code $),或者你可以创建你自己的类来让你创建适当的输入。
$ $ p $ instance(Enum a,Bounded a,Stmt b)=> Stmt(a - > b)其中
重言式f =全部(重言式。f)[minBound .. maxBound]
>重言式$ \x y - > (不是x&& not y)==不是(x&& y)
False
>重言式$ \x y - > (不是x&& not y)== not(x || y)
True
func :: (a -> ... -> a) -> a
isTautology :: (Bool -> ... -> Bool) -> Bool
isTautology (\x -> x && not x)
isTautology (\x y -> x && y || not y)
Bool
is not a problem at all.Bool
, so we'll define a type class with such a function.class Stmt a where
tautology :: a -> Bool
Bool
.-- A Bool is a tautology if it's True.
instance Stmt Bool where
tautology = id
Bool
argument, and whose return type is some type from our class. That way, this instance will be applied multiple times if a function takes multiple arguments.-- A function is a tautology if it always returns a tautology.
instance Stmt b => Stmt (Bool -> b) where
tautology f = tautology (f True) && tautology (f False)
FlexibleInstances
because of the Bool
in the second instance head. To do the same with pure Haskell 98, we'll need to use a suitably-constrained type variable instead. We can for example use Bounded
and Enum
(there are instances for both for Bool
), or you can make your own class that will let you construct the appropriate inputs.instance (Enum a, Bounded a, Stmt b) => Stmt (a -> b) where
tautology f = all (tautology . f) [minBound .. maxBound]
> tautology $ \x y -> (not x && not y) == not (x && y)
False
> tautology $ \x y -> (not x && not y) == not (x || y)
True