Можно ли написать этот код без использования нотации? - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть функция

bar :: MyType -> MyType -> [MyType]

Я хотел бы иметь другую функцию:

foo :: [MyType] -> [MyType]
foo xs = do x <- xs
            y <- xs
            bar x y

Можно ли написать foo без использования записи do? Я думал о чем-то вроде liftA2, но это не сработает.

Ответы [ 2 ]

0 голосов
/ 07 сентября 2018

Вы также можете использовать следующий шаблон для различных арностей для bar:

Arity 2

-- bar :: [MType] -> [MType]
foo :: [MType] -> [MType]
foo xs = join $ bar <$> xs <*> xs

Arity 3

-- bar :: [MType] -> [MType] -> [MType]
foo :: [MType] -> [MType]
foo xs = join $ bar <$> xs <*> xs <*> xs

и т. Д.

Мне нравится это, так как его проще расширить, чем жестко закодированный liftA2.

0 голосов
/ 06 сентября 2018

мы можем использовать алгоритмическое преобразование из do-блоков, как описано в отчете Haskell :

foo :: [MType] -> [MType]
foo xs = xs >>= \x -> xs >>= \y -> bar x y

Но мы можем уменьшить количество лямбда-выражений, пропустив переменную y:

foo :: [MType] -> [MType]
foo xs = xs >>= \x -> xs >>= bar x

и мы также можем опустить переменную x, написав \x -> xs >>= bar x как (xs >>=) . bar

foo :: [MType] -> [MType]
foo xs = xs >>= ((xs >>=) . bar)

Или, как говорит @M.Aroosi, мы можем использовать комбинацию join :: Monad m => m (m a) -> m a и liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c

foo :: [MType] -> [MType]
foo xs = join (liftA2 bar xs xs)
...