3

私は haskell と関数型プログラミングの初心者です。これは非常に単純なことかもしれませんが、検索中に答えが見つかりませんでした。

ここにこの関数 main があります:

main :: IO ()
main = print =<< (`rnd_select` 6) =<< readNumbers

readNumbers :: IO [(Int,Int,Int)]
readNumbers = makeTriples . map rInt . words <$> readFile "somefile"

rInt :: String -> Int
rInt = read

makeTriples :: [a] -> [(a,a,a)]
makeTriples [] = []
makeTriples (x:y:z:zs) = (x,y,z) : makeTriples zs

rnd_select :: [a] -> Int -> IO [a]
rnd_select _  0 = return []
rnd_select [] _ = return []
rnd_select xs count = do r <- randomRIO (0, (length xs)-1)
                         rest <- rnd_select (removeAt (r+1) xs) (count-1)
                         return ((xs!!r) : rest)

removeAt :: Int -> [a] -> [a]
removeAt _ [] = []
removeAt 1 (x:xs) = xs
removeAt k (x:xs) = let r = removeAt (k - 1) xs in x:r

これは IO モナドにラップされているため、値に対して関数を使用したい場合に困難になります。

ここでは bind 関数を使用して入力を rnd_select 関数に適用します。

(`rnd_select` 6) =<< readNumbers

しかし、それを行うには、それを値に部分的に適用する必要があります。

見栄えがよくないと思います。また、関数にさらに変数がある場合、どうすればよいかわかりません。

これらのような関数に値を適用するより良い方法があるかどうか知りたいですか?

4

2 に答える 2

4

省略された引数が最後の引数になるように関数を定義することとは別に、次のように書くことができます

foobar = baz . foo 5 17 29 . bar

ラムダを使用して、最後の引数以外を除外できます。

foobar = baz . (\x -> foo 5 17 x 29 41) . bar

しかし、引数が 2 つだけの場合flipは、良い代替手段です。

main = print =<< flip rnd_select 6 =<< readNumbers
于 2012-08-05T00:01:08.823 に答える
1

rnd_select引数を交換するか、 を使用してflip rnd_select 6 =<< readNumbersください。

于 2012-08-05T00:02:24.103 に答える