Используйте функцию a → b как монадическую функцию a → m b

В настоящее время я играю с основами Haskell и наткнулся на следующий «прецедент»:

ghci> let divideTenBy x | x == 0 = Nothing | otherwise = Just (10 / x)
ghci> let composed = divideTenBy <=< return . (*10) <=< divideTenBy <=< return . (-)5
ghci> Just 5 >>= composed
Nothing
ghci> Just 10 >>= composed
Just (-0.5)

Итак, я в основном смешиваю монадические и чистые функции и объединяю их в монадическую функцию. Это работает, но мне кажется, что return . (*10) обычно нужная вещь, поэтому у меня возникает соблазн определить для нее сокращение, что-то вроде monadify = (return.).

Однако прежде чем я это сделаю, я хотел бы спросить, есть ли уже помощники для решения подобных ситуаций. Конечно, я тоже мог запутаться во всем этом, и есть причины, по которым этого не следует делать. Если это так, пожалуйста, скажите мне.


person Niklas B.    schedule 01.04.2012    source источник
comment
Также обратите внимание, что mu >>= return . f === liftM f mu === fmap f mu (для последнего требуется экземпляр Functor, но он есть у всех приличных Monad). Как показывает ответ Даниэля Вагнера, return . f >=> foo === foo . f. В позиции другого аргумента (>=>) все не так хорошо, foo >=> return . f === fmap f . foo.   -  person Daniel Fischer    schedule 14.09.2012
comment
@Daniel: Хорошо, спасибо за информацию!   -  person Niklas B.    schedule 14.09.2012


Ответы (1)


Нет причин не делать этого. Однако в этом редко возникает необходимость. Например, ваш вариант использования можно переписать как

composed = divideTenBy . (*10) <=< divideTenBy . (-)5
person Daniel Wagner    schedule 01.04.2012
comment
Я удивлен, что мне это не пришло в голову, на самом деле это совершенно очевидно :) Думаю, это прекрасно отвечает на вопрос, спасибо! - person Niklas B.; 01.04.2012