去除常见的haskell管道样板 [英] Removing common haskell piping boilerplate

查看:90
本文介绍了去除常见的haskell管道样板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些很常见的Haskell样板,它出现在很多地方。它看起来像这样(当实例化类时):

  a< = b =(修改a)< =(修改b)

像这样(有正常功能):

  fn xyz = fn(foo x)(foo y)(foo z)

,有时甚至包含元组,如:

  mod(x,y)=(alt x,alt y)

似乎应该有一个简单的方法来减少所有这些样板和不必非常重复自己。 (这些都是简单的例子,但它确实令人讨厌)。我想象有些抽象是为了去除这样的样板而创建的,但我不知道它们叫什么,也不知道在哪里看。任何haskellites都能指向正确的方向吗?

解决方案

对于(< =) code>的情况下,考虑定义比较;然后您可以使用 Data.Ord 。比较,如下所示:

 实例Ord Foo其中
比较=比较修改

请注意,比较可以简单地定义为使用。 html#v:onrel =noreferrer> Data.Function.on



对于 fn

对于 mod

  mod = alt *** alt 

使用 Control.Arrow。(***) - 将 abc 读为 b - >在类型签名中c ;箭头只是一个普通的抽象(如函子或monad),其中的函数是一个实例。你可能想要定义都= join(***)(它本身就是的缩写,都是f = f *** f );我知道至少有一个使用这个别名的人,我认为它应该在Control.Arrow中。

所以,一般来说,答案是:combinators,组合器,组合器!这直接与点免费风格相关联。它可以被过度使用,但是当组合器存在于你的情况下时,这样的代码不仅可以更清晰,更短,而且可以更容易阅读:你只需要学习一次抽象,然后在读取代码时将它应用到任何地方。



我建议使用 Hoogle 来查找这些组合子;当你认为自己看到了定义的一般模式时,尝试抽象出你认为常见部分是什么,采取何种结果并在Hoogle上搜索。你可能会发现一个combinator只是你想要的。



例如,对于你的 mod 你可以抽象出 alt ,产生 \f(a,b) - > (fa,fb),然后搜索其类型,(a,a) - >(b,b) - 有一个完全匹配,但它在fgl图库中,你不想依赖它。尽管如此,你仍然可以看到按类型搜索的能力确实是非常有价值的!

还有一个带GHCi集成的Hoogle命令行版本;请参阅 HaskellWiki页面获取更多信息。



< (还有 Hayoo ,它搜索整个 Hackage ,但对于类型而言稍微不够聪明;你使用的是个人偏好。)


I have some pretty common Haskell boilerplate that shows up in a lot of places. It looks something like this (when instantiating classes):

a <= b = (modify a) <= (modify b)

like this (with normal functions):

fn x y z = fn (foo x) (foo y) (foo z)

and sometimes even with tuples, as in:

mod (x, y) = (alt x, alt y)

It seems like there should be an easy way to reduce all of this boilerplate and not have to repeat myself quite so much. (These are simple examples, but it does get annoying). I imagine that there are abstractions created for removing such boilerplate, but I'm not sure what they're called nor where to look. Can any haskellites point me in the right direction?

解决方案

For the (<=) case, consider defining compare instead; you can then use Data.Ord.comparing, like so:

instance Ord Foo where
  compare = comparing modify

Note that comparing can simply be defined as comparing f = compare `on` f, using Data.Function.on.

For your fn example, it's not clear. There's no way to simplify this type of definition in general. However, I don't think the boilerplate is too bad in this instance.

For mod:

mod = alt *** alt

using Control.Arrow.(***) — read a b c as b -> c in the type signature; arrows are just a general abstraction (like functors or monads) of which functions are an instance. You might like to define both = join (***) (which is itself shorthand for both f = f *** f); I know at least one other person who uses this alias, and I think it should be in Control.Arrow proper.

So, in general, the answer is: combinators, combinators, combinators! This ties directly in with point-free style. It can be overdone, but when the combinators exist for your situation, such code can not only be cleaner and shorter, it can be easier to read: you only have to learn an abstraction once, and can then apply it everywhere when reading code.

I suggest using Hoogle to find these combinators; when you think you see a general pattern underlying a definition, try abstracting out what you think the common parts are, taking the type of the result, and searching for it on Hoogle. You might find a combinator that does just what you want.

So, for instance, for your mod case, you could abstract out alt, yielding \f (a,b) -> (f a, f b), then search for its type, (a -> b) -> (a, a) -> (b, b) — there's an exact match, but it's in the fgl graph library, which you don't want to depend on. Still, you can see how the ability to search by type can be very valuable indeed!

There's also a command-line version of Hoogle with GHCi integration; see its HaskellWiki page for more information.

(There's also Hayoo, which searches the entirety of Hackage, but is slightly less clever with types; which one you use is up to personal preference.)

这篇关于去除常见的haskell管道样板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆