3

現在の画面幅を 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 ? ...

「スクリーン幅:」のような文字列にマジック関数を渡したいのですが、現在のスクリーン幅を追加して、「スクリーン幅: 1680」を取得します。IO 整数と共通文字列を連結するにはどうすればよいですか? で動作しshowますか?

誰でもそれを手伝ってもらえますか?

4

4 に答える 4

5

まず、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

...その後getScreenWidth2 回実行されます...確かに、この特定のアクションでは問題になりそうにありませんが、ファイル、データベース、または Web サイトから整数を読み取るアクションである場合は、それを実行することがわかります。 2 回は望ましくない場合があります。

通常は、 のような関数を記述しない方がよいでしょうlabelIOInteger。代わりに、次のようにします。

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

...そのため、2 つの異なる計算に戻り値を使用する必要がある場合は、次のように簡単にリファクタリングできます。

screenWidth <- getScreenWidth
let widthLabel = labelInteger "Screen Width" screenWidth
isPortrait <- liftM (screenWidth <) getScreenHeight
于 2013-04-24T16:58:21.863 に答える
2
magic_function :: IO Integer -> String -> IO String
magic_function num msg = do
                            n <- num
                            return (msg ++ (show n))
于 2013-04-24T16:55:48.063 に答える
2

提案された複製実際にあなたが必要とする答えを与えますが、そもそもあなたがこれを尋ねていないことが明らかだったとしたら. :]

一般に、型が である値を直接操作することはできませんIO something。この型は、 でsomethingラップされた型の値でIOはなく、実行時IOに型の値を生成する可能性のあるプロシージャを表しsomethingます。IO something結局、値を複数回使用すると、異なる「何か」になる可能性があります。

したがって、あなたの場合、単純にStringon を連結することはできません。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通常どおり文字列を連結できます。

于 2013-04-24T16:58:47.613 に答える
1

私はあなたがこれを望んでいると思います:

magic :: IO Integer -> String -> IO String
magic ios s =
  do i <- ios
     return $ s ++ ": " ++ (show i)
于 2013-04-24T16:56:31.933 に答える