拆除普通的haskell管道样板

So8*_*res 6 haskell

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

a <= b = (modify a) <= (modify b)
Run Code Online (Sandbox Code Playgroud)

像这样(具有正常功能):

fn x y z = fn (foo x) (foo y) (foo z)
Run Code Online (Sandbox Code Playgroud)

有时甚至是元组,如:

mod (x, y) = (alt x, alt y)
Run Code Online (Sandbox Code Playgroud)

似乎应该有一种简单的方法来减少所有这些样板,而不必重复自己.(这些都是简单的例子,但确实很烦人).我想是为了删除这样的样板而创建的抽象,但我不确定它们被称为什么,也不知道在哪里看.任何haskellites可以指向我正确的方向吗?

ehi*_*ird 12

对于这种(<=)情况,请考虑定义compare; 然后你可以使用Data.Ord.comparing,如下所示:

instance Ord Foo where
  compare = comparing modify
Run Code Online (Sandbox Code Playgroud)

请注意,comparing可以comparing f = compare `on` f使用Data.Function.on简单地定义为.

就你的fn例子而言,目前尚不清楚.一般来说,没有办法简化这种类型的定义.但是,在这种情况下,我不认为样板太糟糕了.

用于mod:

mod = alt *** alt
Run Code Online (Sandbox Code Playgroud)

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

所以,一般来说,答案是:组合器,组合器,组合器!这与无风格直接相关.它可能过头了,但是当组合器适合你的情况时,这样的代码不仅更简洁,更简单,更容易阅读:你只需要学习一次抽象,然后在阅读代码时可以随处应用.

我建议使用Hoogle找到这些组合器; 当你认为你看到定义的一般模式时,尝试抽象你认为常见的部分是什么,取结果的类型,并在Hoogle上搜索它.您可能会找到一个能够满足您需求的组合器.

所以,例如,对于你的mod情况,你可以抽象alt,屈服\f (a,b) -> (f a, f b),然后搜索它的类型,(a - > b) - >(a,a) - >(b,b) - 这是完全匹配,但它是在fgl图库中,您不想依赖它.不过,你可以看到按类型搜索的能力确实非常有价值!

还有一个命令行版本的Hoogle与GHCi集成; 有关更多信息,请参阅其HaskellWiki页面.

(还有Hayoo,它搜索整个Hackage,但是类型稍微不那么聪明;你使用哪一个取决于个人偏好.)