return
функция в Haskell имеет мало общего с return
ключевого слова в императивных языках программирования, это просто обычная функция с обычной сигнатуры типа:
return :: Monad m => a -> m a
В принципе, return
принимает любое старое значение и «подъемниками «Это в монаду. Это немного яснее, что делает эта функция при замене m
с конкретным типом, как Maybe
:
return :: a -> Maybe a
Там только одна реализация функции выше, и это Just
, так return = Just
для Maybe
монады.
В вашем случае вы используете функцию monad, (->) r
, также часто называемую «читающей» монадой. Выполнение же замены, как с Maybe
, мы получаем следующую подпись:
return :: a -> r -> a
Эту функцию также имеет только одну реализацию, которая должна игнорировать свой второй аргумент и вернуть его первым. Это то, что делает const
, поэтому return = const
для функций.
Вопрос о том, «когда использовать return
» является разумным, но она должна иметь больше смысла после понимания выше: вы должны использовать return
когда возвращаемое значение из функции передается >>=
не монадический , поэтому его нужно «снять». Например, следующее будет ошибка типа:
Just 3 >>= \x -> x + 1
В частности, правая рука должна возвращать Maybe Int
, но он возвращает только в Int
. Таким образом, мы можем использовать return
для получения значения правильного типа:
Just 3 >>= \x -> return (x + 1)
Однако рассмотрит аналогичное выражение.В следующем случае, с помощью return
будет ошибка типа:
Just [("a", 1), ("b", 2)] >>= \l -> lookup "c"
Это потому, что результат функции lookup
является уже значение Maybe Int
, поэтому использование return
будет производить Maybe (Maybe Int)
, что было бы неправильно.
Возвращаясь к вашему примеру с помощью функции монады, (n+)
уже зависит от типа Int -> Int
, поэтому использование return
было бы неправильно (он будет производить функцию типа Int -> Int -> Int
). Однако d + d
- это всего лишь значение типа Int
, поэтому вам нужно return
, чтобы поднять значение в монаду.
Стоит отметить, что в обоих случаях, вы всегда можете заменить return
с его основной реализации. Вы можете использовать Just
вместо return
при использовании монады Maybe
, и вы можете использовать const
вместо return
при использовании функции monad. Тем не менее, есть две веские причины использовать return
:
return
Использование позволяет писать функции, которые работают с более чем одним видом монады. То есть, return
получает вас Полиморфизм.
Это очень идиоматическое использовать return
поднять простые значения в монадический тип, так что яснее и менее шумный, чтобы всегда видеть return
вместо того, чтобы видеть много различных функций с разными именами.
well yes - 'return' используется для вытягивания значений в вашу монаду - как и любая другая функция, которую вы просто должны смотреть на типы (' return' - это не то, что вы знаете из C-подобных языков) - кроме этого: зачем использовать monad-instance of '(->) a' здесь вообще? это просто запутывает все - это какое-то упражнение? – Carsten
см.: '\ N -> (n +)' уже имеет желаемый тип 'Int -> (Int -> Int)' (ваша монада есть '(->) Int') - но, конечно,' d + d' имеет (он имеет тип 'Int') - поэтому вы используете' return (d + d) = \ _ -> (d + d) '(помните' '' d-> ... 'в' >> = (\ d -> ...) 'нужно вернуть монадическое значение - это' Int -> a' здесь) – Carsten
@Carsten: Хороший ответ, я думаю, вы можете ответить на вопрос, если я принимаю этот вопрос, если не появятся лучшие ответы вдоль. Кстати, я новичок в Haskell, поэтому я пытаюсь понять, что такое монада в Haskell. – prosseek