Сейчас я работаю над 20 промежуточными упражнениями на Haskell, и это довольно забавное упражнение. Он включает в себя реализацию различных экземпляров классов типов Functor
и Monad
(и функций, которые принимают Functor
и Monad
в качестве аргументов), но с милыми именами, такими как Furry
и Misty
, чтобы скрыть то, что мы делаем (создает интересный код).
Я пытался сделать кое-что из этого в бесточечном стиле, и мне стало интересно, существует ли общая схема превращения точечного (?) определения в бесточечное определение. Например, вот класс типов для Misty
:
class Misty m where
unicorn :: a -> m a
banana :: (a -> m b) -> m a -> m b
(функции unicorn
и banana
— это return
и >>=
, если это не очевидно) и вот моя реализация apple
(эквивалентна flip ap
):
apple :: (Misty m) => m a -> m (a -> b) -> m b
apple x f = banana (\g -> banana (unicorn . g) x) f
В более поздних частях упражнений вы реализуете версии liftM
, liftM2
и т. д. Вот мои решения:
appleTurnover :: (Misty m) => m (a -> b) -> m a -> m b
appleTurnover = flip apple
banana1 :: (Misty m) => (a -> b) -> m a -> m b
banana1 = appleTurnover . unicorn
banana2 :: (Misty m) => (a -> b -> c) -> m a -> m b -> m c
banana2 f = appleTurnover . banana1 f
banana3 :: (Misty m) => (a -> b -> c -> d) -> m a -> m b -> m c -> m d
banana3 f x = appleTurnover . banana2 f x
banana4 :: (Misty m) => (a -> b -> c -> d -> e) -> m a -> m b -> m c -> m d -> m e
banana4 f x y = appleTurnover . banana3 f x y
Теперь banana1
(эквивалентно liftM
или fmap
) я смог реализовать в бесточечном стиле с помощью подходящего определения appleTurnover
. Но с тремя другими функциями мне пришлось использовать параметры.
У меня вопрос: есть ли способ превратить подобные определения в бесточечные определения?
@pl
в lambdabot). - person ehird   schedule 30.12.2011