Присоединяйтесь к двум IO с помощью - в haskell - PullRequest
0 голосов
/ 16 января 2019

Мне нужно соединить два IO String с - между ними. Вот то, что я придумал, который работает - как правильно?

import System.Environment
f :: String -> String -> IO String
f x y = (foldl1 (++)) <$> sequence [(getEnv x),(return "-"),(getEnv y)]

Ответы [ 3 ]

0 голосов
/ 16 января 2019

Здесь можно использовать функцию аппликативного стиля:

f :: String -> String -> IO String
f x y = withHyp <$> getEnv x <*> getEnv y
    where withHyp ex ey = ex ++ '-' : ey

Итак, здесь мы соединяем два String, которые затем соединяются с гипеном в середине с помощью функции withHyp.

Или для получения списка переменных среды, которые нам нужно получить, мы можем использовать mapM и выполнить intercalate:

import Data.List(intercalate)

f :: [String] -> IO String
f xs = intercalate "-" <$> mapM getEnv xs
0 голосов
/ 16 января 2019

Честно говоря, идея вашего подхода на самом деле выглядит довольно вменяемой для меня. Начнем с того, что я, вероятно, использовал бы concat intsead из foldl1 (++) и бросил бы несколько паренсов, чтобы получить:

f x y = concat <$> sequence [getEnv x, return "-", getEnv y]

Это действительно не кажется мне таким уж плохим. Но если бы я действительно хотел продвинуться дальше, вот некоторые мысли, которые у меня были бы. Во-первых, я бы вспомнил функцию intercalate.

f x y = intercalate "-" <$> sequence [getEnv x, getEnv y]

Также есть удобное сокращение для применения функции к каждому элементу списка; mapM f = sequence . map f. Итак:

f x y = intercalate "-" <$> mapM getEnv [x,y]

Я бы остановился там; это выглядит довольно чистым и ремонтопригодным для меня.

0 голосов
/ 16 января 2019

Один из способов объединения двух IO String будет:

dash :: IO String -> IO String -> IO String
dash x y = do
    s1 <- x
    s2 <- y
    return $ s1 <> "-" <> s2

Мы «распаковываем» каждый из x и y, чтобы получить содержащиеся String s, а затем «перезаписываем» их дефисом (используя аналогию для Функторов).

Может быть сокращено до:

dash = liftA2 (\s1 s2 -> s1 <> "-" <> s2)

Где liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c берет двоичную функцию и «поднимает» ее в двоичную функцию на Applicative с, которые являются надмножеством Monad с.

Ваш f может быть реализован как f x y = dash (getEnv x) (getEnv y).

...