Здесь используется $
, поскольку он имеет более низкий приоритет, чем обычное применение функции.
Другой способ написать этот код выглядит так:
instance Monad [] where
xs >>= f = (concat . map f) xs
Идея состоит в том, чтобы сначала создать функцию (concat . map f
), а затем применить ее к аргументу (xs
). Как показано, это также можно сделать, просто поместив круглые скобки вокруг первой части.
Обратите внимание, что пропуск $
в исходном определении невозможен, это приведет к ошибке типа. Это связано с тем, что оператор композиции функций (.
) имеет более низкий приоритет, чем обычное приложение функции, эффективно превращающее выражение в:
instance Monad [] where
xs >>= f = concat . (map f xs)
Что не имеет смысла, потому что второй аргумент оператора композиции функций вообще не является функцией. Хотя следующее определение имеет смысл:
instance Monad [] where
xs >>= f = concat (map f xs)
Кстати, это тоже определение, которое я бы предпочел, потому что мне кажется, что оно намного понятнее.