gpt4 book ai didi

haskell - 如何编写一个以可变参数函数作为参数的 Haskell 函数

转载 作者:行者123 更新时间:2023-12-03 06:52:30 25 4
gpt4 key购买 nike

我正在尝试创建一个函数,该函数将可变参数函数作为参数,即

func :: (a -> ... -> a) -> a

我怎样才能做到这一点?

我读过polyvariadic functions我确信Oleg already did it ,但是我在尝试将模式应用于以可变参数函数作为参数的函数时迷失了。特别是 Olegs 方法似乎只适用于 glasgow 扩展,我希望该解决方案能够在纯 Haskell 98 中工作(就像 Text.Printf 那样)。

我问的原因是我正在尝试构建一个函数,该函数将 bool 函数作为参数并检查它是否是同义反复,即

isTautology :: (Bool -> ... -> Bool) -> Bool

这样就可以输入:

isTautology (\x -> x && not x)
isTautology (\x y -> x && y || not y)

我的问题是,我一直在阅读关于将返回类型设为类型变量(以便它可以是结果或另一个函数)的技巧,但我的返回类型是固定的(Bool)。

最佳答案

诀窍是创建一个类型类,您将为其定义函数实例和返回类型实例。事实上它是一个 Bool 根本不是问题。

我们正在尝试编写一个接受可变参数并返回 Bool 的函数,因此我们将使用这样的函数定义一个类型类。

class Stmt a where
tautology :: a -> Bool

接下来,我们为可变参数函数的返回类型定义一个实例。在本例中,为 Bool

-- A Bool is a tautology if it's True.
instance Stmt Bool where
tautology = id

关键部分是采用 Bool 参数的函数的下一个实例,其返回类型是我们类中的某种类型。这样,如果函数采用多个参数,则该实例将被多次应用。

-- 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,因为第二个实例头中有 Bool。要对纯 Haskell 98 执行相同操作,我们需要使用适当约束的类型变量。例如,我们可以使用 BoundedEnum (Bool 都有实例),或者您可以创建自己的类,让您构造适当的输入。

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

关于haskell - 如何编写一个以可变参数函数作为参数的 Haskell 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8353845/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com