繁体   English   中英

在Haskell中连接String和IO Integer

[英]Concatenate String and IO Integer in Haskell

我编写了一个函数,将当前屏幕宽度作为IO Integer返回(到目前为止工作)。

getScreenWidth:: IO Integer
getScreenWidth = do
                    (sx, sy, w, h) <- getScreenDim 0
                    return $ sx

现在我想将屏幕宽度添加到字符串:

> magic_function :: IO Integer -> String -> ... magic output type
> magic_function = ... ? this is where i am stack at ? ...

我想将魔术函数传递给一个字符串,比如“Screen Width:”,我希望它添加当前的屏幕宽度,这样我就可以得到“Screen Width:1680”。 如何连接IO整数和常用字符串? 它适用于show吗?

有人可以帮我吗?

首先,忘记IO:

labelInteger :: String -> Integer -> String
labelInteger label number = label ++ ": " ++ show number

现在担心IO:

import Control.Monad (liftM, liftM2)

labelIOInteger :: String -> IO Integer -> IO String
labelIOInteger label ioNumber = liftM (labelInteger label) ioNumber

用作例如labelIOInteger "Screen Width" getScreenWidth ...但要注意! 如果您这样做:

widthLabel <- labelIOInteger "Screen width" getScreenWidth
isPortrait <- liftM2 (<) getScreenWidth getScreenHeight

...然后getScreenWidth将执行两次...对于这个特定的操作,这不太可能是一个问题,但如果它是一个从文件或数据库或网站读取整数的操作,你可以看到执行两次可能是不受欢迎的。

通常最好不要编写像labelIOInteger这样的labelIOInteger ,而是这样做:

widthLabel <- liftM (labelInteger "Screen Width") getScreenWidth

...因此,如果您发现自己需要将返回值用于两个不同的计算,则可以轻松地对此进行重构:

screenWidth <- getScreenWidth
let widthLabel = labelInteger "Screen Width" screenWidth
isPortrait <- liftM (screenWidth <) getScreenHeight
magic_function :: IO Integer -> String -> IO String
magic_function num msg = do
                            n <- num
                            return (msg ++ (show n))

建议的副本实际上给你所需要的答案,但我想,如果这是显而易见的,你怎么也不会首先会问这个。 :]

通常,您不能直接使用类型为IO something的值执行任何操作。 这种类型不表示的类型的值something包裹在IO ,而是一个过程可能使用IO产生的类型的值something被执行时。 毕竟,如果你不止一次使用IO something值,它可能会有所不同。

所以在你的情况下,你不能简单地连接String ; 你必须定义一个执行另一个IO程序的新IO程序,然后连接它产生的值。 一般表格看起来像这样:

someFunction :: a -> b -> c
someFunction a b = ...

someProcedure :: IO a -> b -> IO c
someProcedure a b = do aValue <- a -- this executes "a"
                       return $ someFunction aValue b

有更短的方法来编写它,但我认为这有助于拼写出来。 具体取决于你实际在做什么,当然 - 对于你的程序,你可以使用show将整数转换为String ,然后像往常一样连接字符串。

我想你想要这个:

magic :: IO Integer -> String -> IO String
magic ios s =
  do i <- ios
     return $ s ++ ": " ++ (show i)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM