在 haskell 中加入两个 IOs 和 -
Join two IOs with - in haskell
我需要加入两个 IO String
,中间有一个 -
。这是我想出的,它有效 - 什么是正确的方法?
import System.Environment
f :: String -> String -> IO String
f x y = (foldl1 (++)) <$> sequence [(getEnv x),(return "-"),(getEnv y)]
连接两个 IO String
的一种方法是:
dash :: IO String -> IO String -> IO String
dash x y = do
s1 <- x
s2 <- y
return $ s1 <> "-" <> s2
我们 "unbox" 每个 x
和 y
得到包含的 String
s,然后用连字符“重新装箱”它们(使用 Functors 的类比) .
可以简写为:
dash = liftA2 (\s1 s2 -> s1 <> "-" <> s2)
其中 liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
采用二元函数,"lifts" 将其转化为 Applicative
上的二元函数,Monad
是 Monad
的超集。
然后您的 f
可以实现为 f x y = dash (getEnv x) (getEnv y)
。
您可以在此处使用应用样式函数:
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
老实说,你的方法背后的想法对我来说实际上看起来很理智。首先,我可能会使用 concat
intsead of foldl1 (++)
,并删除一些括号,让我们:
f x y = concat <$> sequence [getEnv x, return "-", getEnv y]
这对我来说真的不是那么糟糕。但如果我真的想更进一步,我会有以下一些想法。首先,我会回忆一下 intercalate
函数。
f x y = intercalate "-" <$> sequence [getEnv x, getEnv y]
还有一个方便的 shorthand 可以将函数应用于列表的每个元素; mapM f = sequence . map f
。所以:
f x y = intercalate "-" <$> mapM getEnv [x,y]
我会到此为止;对我来说它看起来很干净且易于维护。
我需要加入两个 IO String
,中间有一个 -
。这是我想出的,它有效 - 什么是正确的方法?
import System.Environment
f :: String -> String -> IO String
f x y = (foldl1 (++)) <$> sequence [(getEnv x),(return "-"),(getEnv y)]
连接两个 IO String
的一种方法是:
dash :: IO String -> IO String -> IO String
dash x y = do
s1 <- x
s2 <- y
return $ s1 <> "-" <> s2
我们 "unbox" 每个 x
和 y
得到包含的 String
s,然后用连字符“重新装箱”它们(使用 Functors 的类比) .
可以简写为:
dash = liftA2 (\s1 s2 -> s1 <> "-" <> s2)
其中 liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
采用二元函数,"lifts" 将其转化为 Applicative
上的二元函数,Monad
是 Monad
的超集。
然后您的 f
可以实现为 f x y = dash (getEnv x) (getEnv y)
。
您可以在此处使用应用样式函数:
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
老实说,你的方法背后的想法对我来说实际上看起来很理智。首先,我可能会使用 concat
intsead of foldl1 (++)
,并删除一些括号,让我们:
f x y = concat <$> sequence [getEnv x, return "-", getEnv y]
这对我来说真的不是那么糟糕。但如果我真的想更进一步,我会有以下一些想法。首先,我会回忆一下 intercalate
函数。
f x y = intercalate "-" <$> sequence [getEnv x, getEnv y]
还有一个方便的 shorthand 可以将函数应用于列表的每个元素; mapM f = sequence . map f
。所以:
f x y = intercalate "-" <$> mapM getEnv [x,y]
我会到此为止;对我来说它看起来很干净且易于维护。