是否有使用模式作为谓词功能的便捷方法?


10

最近,我遇到了需要将谓词函数传递给另一个函数的情况,并且我经常寻找的逻辑本质上是“此值是否与该模式匹配?”

在声明,do块和列表理解中,模式匹配似乎是首选,但是有许多函数采用谓词a -> Bool,在某种情况下以某种方式传递模式非常方便。例如,takeWhileuntilfindspan,等。

到目前为止,我一直在做\a -> case a of MyCons _ -> True; otherwise -> False,或者写一个la命名函数,let myPred (MyCons _) = True; myPred _ = False in但是它们看起来都非常丑陋,而且不是很惯用。“显而易见的”(错误的)方式将是类似的,\(MyCons _) -> True但是由于自然而然地局部化而引发了错误,甚至感觉到必须有一种更清洁的方式。

有没有更简洁/干净的方式来执行这种事情?还是我做事完全是错误的方式?


1
也许这是一种“个人喜好”的事情,但是,如果您只需要在一个地方使用此谓词,我会对let您不喜欢的子句感到非常满意-尽管我更喜欢等效的where子句,因此这不会使主要定义混乱。当然,如果最终不止一次需要此实用程序,则可以将其定义为顶级功能。
罗宾·齐格蒙德

当然可以。我的问题是由Haskell通常有多么简洁引起的。通常感觉惯用的Haskell几乎没有重复的想法,并且将起毛减少到最低限度。因此,我什至不一定认为let myPred...样式不好,但是感觉比我想一个非常简单的想法要冗长得多,这使我想知道我是否在树错了树。
David Sampson

2
您可能会看到棱镜(从镜头看)。它们就像一流的可组合模式
luqui

1
我认为我们需要看一个使用这种类型的高阶函数的示例。我有些想说的问题是设计首先需要这样的谓词。
chepner

为此,Haskell98方法是为您的数据类型(例如maybe :: b -> (a -> b) -> Maybe a -> b和)定义大小写匹配(解构)函数bool :: a -> a -> Bool -> a,然后将其与产生布尔值的函数一起用作参数。例如myCons z f (MyCons x) = f x ; myCons z f _ = z,然后致电myCons False (const True) aMyConsValue。这几乎就是您所写的内容,只是通过函数自变量引入了另一层“间接” /“抽象”。
尼斯

Answers:


7

您可以使用语言扩展LambdaCase来使用\case MyCons _ -> True; _ -> False,尽管这不会保存那么多字符。

我相信您可以编写一系列函数constructedWith :: (Generic a) => (b -> a) -> a -> BoolconstructedWith2 :: (Generic a) => (b -> c -> a) -> a -> Bool但是如果不花几个小时进行测试,我对Generics的能力就不足以实现它。我将尝试这种方法,并在我能解决问题或死胡同的情况下编辑我的答案。

编辑:是的,您可以做到!这是我的代码的链接,该链接从头开始实现了所有步骤:

https://repl.it/@lalaithion/ConstructedWith

但是,对所有通用代码管道使用http://hackage.haskell.org/package/generic-deriving-1.13.1/docs/Generics-Deriving-ConNames.html之类的方法可能更好。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.