(-1,-1),( - 1,0),( - 1,1),(0,-1),(0,1),(1,-1), (1,0),(1,1)]在Haskell中? [英] What are some better ways to write [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)] in Haskell?

查看:213
本文介绍了(-1,-1),( - 1,0),( - 1,1),(0,-1),(0,1),(1,-1), (1,0),(1,1)]在Haskell中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  [( -  1,-1) ,( -  1,0),( -  1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]  - 否(0,0)

请注意,列表中没有(0,0)。我使用(dx,dy)元组向上,向下,向左,向右和从坐标对角搜索。



每次我写它,我都觉得应该有一个更简洁,和/或更易于阅读的方式来定义它。我对Haskell比较陌生,我想到了Applicative / Functor / Monad技巧,应该有一个很好的做法。



我试过了:$($ -1),( - 1,0),( - 1,1),(0 ,-1),(0,1),(1,-1),(1,0),(1,1)]

有时最好写出来,但我不认为这是其中的一种。 (0,0)不包括在内,你不得不仔细阅读它。

  map(\ [a,b]  - >(a,b))$ delete [0,0] $ sequence $ replicate 2 [-1,0,1] 

我喜欢上面的那个,因为我把2放在那里,这是一个很好的明确的方式来说我们正在做同样的事情两次,但我不能接受前面的地图与大的不安全的lambda和2名。

  [(dx,dy)|设a = [-1,0,1],dx <-a,dy <-a,(dx,dy)/ =(0,0)] 
pre>

这个名称太多了,但是完全按照它的设计使用了列表理解。对于那些真正喜欢列表解析的人来说,阅读起来可能会更容易些,但我不喜欢所有的名字。

  let x (0,0)$(,)< $>中的= [-1,0,1] x * x 

这个看起来更漂亮,但我没有那个2,我有一个名字。这是我目前最喜欢的,但它并不完美。



我认为如果我理解如何更好地写这些,我可能会对Functors / Monads有更深的理解或类似的。我已经阅读了很多关于它们的文章,并且我已经听到了一堆像fmap / mconcat / etc这样的词,但我不知道在这种情况下应该选择哪一个。

解决方案

实际上,在这种情况下,我认为最好把它写出来。

  neighbors = [(-1,-1),( -  -1) (0,1),(0,1)
,(1,-1),(1,0),(1,1),(-1,1)
, ]

没有办法可以比这更明白了。



当然,还有更多的简洁替代品。作为一个物理学家,我倾向于
$ b $ pre $ [(round $ - sinφ,round $ - cosφ)| φ< - π/ 4,π/ 2 ... 2 *π]

当然,计算起来会更昂贵,但如果您只在一个地方定义此列表并在整个程序中重新使用它,则无关紧要。这里的订单有所不同,不确定是否重要。


I've run in to a few situations where I need the list:

[(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)] -- no (0,0)

Note that there is no (0,0) in the list. I use the (dx,dy) tuples to search up, down, left, right and diagonally from a coordinate.

Every time I write it I feel like there should be a more concise, and/or easier to read way to define it. I'm relatively new to Haskell and I figure somewhere in the bag of Applicative/Functor/Monad tricks there should be a neat way to do this.

I've tried:

[(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]

Sometimes it's better just to write it out, but I don't think this is one of those times. It's not obvious with a glance that (0,0) isn't included, and you have to read it a bit to notice the pattern.

map (\[a,b] -> (a,b)) $ delete [0,0] $ sequence $ replicate 2 [-1,0,1]

I like the one above because I get to put the "2" in there which is a nice explicit way to say "We're doing the same sort of thing twice", but I can't accept the map in front with the big unsafe lambda and 2 names.

[(dx,dy) | let a = [-1,0,1], dx <- a, dy <- a, (dx,dy) /= (0, 0)]

This one has too many names in it, but uses the list comprehension exactly as it is designed. It might be easier to read for somebody who really likes list comprehensions, but I don't like all the names.

let x = [-1,0,1] in delete (0,0) $ (,) <$> x <*> x

That one looks prettier imo, but I don't have that "2" in there, and I have a name. This is my favorite so far, but it doesn't feel perfect.

I think if I understood how to write this better I might have a deeper understanding of Functors/Monads or the like. I've read about them quite a bit, and I've heard a bunch of words like fmap/mconcat/etc, but I don't know which one to grab for in this situation.

解决方案

Actually, I think it's indeed best to write it out explicitly in this case. Just align it reasonably, and no questions stay open whatsoever:

neighbours = [ (-1,-1), (-1,0), (-1,1)
             , ( 0,-1),         ( 0,1)
             , ( 1,-1), ( 1,0), ( 1,1) ]

There's no way any alternative could be more self-explanatory than this.

Of course, there are more concise alternatives. Being a physics guy, I'd tend to

   [ (round $ - sin φ, round $ - cos φ) | φ <- [pi/4, pi/2 .. 2*pi] ]

which is of course more expensive to compute, but that doesn't matter if you only define this list at one place and re-use it from all over you program. The order is different here, not sure if that matters.

这篇关于(-1,-1),( - 1,0),( - 1,1),(0,-1),(0,1),(1,-1), (1,0),(1,1)]在Haskell中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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