Подтвердить что ты не робот

Haskell map/zip Vs. список

Какое из следующего вы, скорее всего, напишете?

r = zip xs $ map sqrt xs

или

r = [(x, sqrt x) | x <- xs]

Пример кода в Интернете, по-видимому, указывает на то, что первое является более распространенным и предпочтительным.

4b9b3361

Ответ 1

Я бы, скорее всего, написал

map (\x -> (x, sqrt x)) xs

Если вы предпочитаете без ограничений, приведенное выше эквивалентно (после импорта Control.Monad и Control.Monad.Instances)

map (ap (,) sqrt) xs

Еще одна альтернатива, которая еще не упоминалась,

zipWith (,) xs (map sqrt xs)

Ответ 2

Люди, которые проводят слишком много времени в #haskell, вероятно, напишут, что

r = map (id &&& sqrt) xs

(&&&) - забавный комбинатор, определенный в Control.Arrow. Его фактическая подпись типа сложна, потому что она обобщена на все экземпляры Arrow. Но он часто используется с экземпляром (->) Arrow, что приводит к сигнатуре этого типа:

(&&&) :: (a -> b) -> (a -> c) -> a -> (b, c)

Ответ 3

Хотя я не очень часто их использую, в этом случае я думаю, что предпочел бы версию для понимания списка, поскольку мне кажется, что она чище.

Если вы находитесь в стиле без очков, вам может понравиться и это:

f = zip `ap` map sqrt

ap работает в Control.Monad, и в этом случае его можно рассматривать как комбинатор S, который обобщает приложение в исчисление SKI:

ap f g x == f x (g x)
ap const const == id

Как указывает Конал, это также может быть обобщено от Monad до Applicative (import Control.Applicative):

f = zip <*> map sqrt

Ответ 4

Я бы, вероятно, написал map/zip, а потом пожелал, чтобы я написал понимание списка.

Ответ 5

Для определенных типов проблем (Project Euler в частности), этот конкретный случай возникает настолько часто, что я написал следующий небольшой помощник:

with :: (a -> b) -> a -> (a,b)
with f a = (a, f a)

Это позволяет записать ваш пример:

r = map (with sqrt) xs

Ответ 6

Я редко использую списки, но оба они денди. Просто используйте тот, который упрощает чтение кода.

Ответ 7

Я больше "Старая школа" Haskellier, поэтому я бы использовал zip `ap` map sqrt и позже реорганизовал его, чтобы использовать <*> вместо ap.

Аппликация - это новая Монада. (В смысле "что делают Cool Haskell Kids в эти дни?" )