1

こんにちは、私の問題です。これは私の実行中のコードです。これで問題ありません。

showBalls = do
      howMany <- getInt
      return . take HowMany $ repeat 9

getInt は、ユーザー入力の Int を取得するためにいくつかのチェックを行います。しかし、私の質問は、モナドを使用してコードのこの部分を書き直す方法はありますか?

私の目的は、 >>= を使用して、次のような最終的な 1 行の関数を作成することです。

showBalls = fmap (take <$> (repeat 9)) getLine

ただし、機能しません(予想どおり)。なにか提案を?

4

3 に答える 3

2

私もそれを自分で手に入れましたが、ラムダ表記を使用しています:)

showBalls = getInt >>= (\a -> return . take a $ repeat 9 )
于 2013-01-09T18:18:48.687 に答える
2

を使用flipして の引数を逆にすることができますtake。これにより、 に適用repeat 9して関数を取得できるようになります。

> :t flip take (repeat 9)
flip take (repeat 9) :: Num a => Int -> [a]

で使用>>=するには、関数getIntが必要です。Int -> IO a

> :t (getInt >>=)
(getInt >>=) :: (Int -> IO b) -> IO b

それを取得するには、次のように構成しますreturn(これは、すべてのモナドで機能するためですがm [a]、リストにも制限されているためです。上記の型から、 getsおよびbecome ):mIOb[a]

> :t return . flip take (repeat 9)
return . flip take (repeat 9) :: (Monad m, Num a) => Int -> m [a]

最終的な式は次のとおりです。

> :t getInt >>= return . flip take (repeat 9)
getInt >>= return . flip take (repeat 9) :: Num a => IO [a]

しかし、前述したように、オリジナルよりも厳密に優れているとは確信していません。より有用な知識として、GHCi で式とその型をいじることは、そのような変換を発明する良い方法です。

于 2013-01-09T18:18:19.230 に答える
1

私はこれがうまくいくと信じています:

showBalls = (liftM . flip take $ repeat 9) getInt

おそらくポイントフリーの方法もありますが、私はそれを理解できませんでした。

于 2013-01-09T18:16:44.657 に答える