Altair
Altair

Reputation: 67

How to use bind (>>=) on function with multiple variables

I am a newbie to haskell and functional programming. This might be a very simple thing, but I haven't found an answer while searching.

I have this function main here:

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

This is wrapped in the IO-monad and that is what makes it hard when i want to use functions on the values.

Here i use the bind function to apply the input to the rnd_select function:

(`rnd_select` 6) =<< readNumbers

But in order to do that I have to partially apply it to a value.

I don't think it looks very good and I don't know how I would do it if the function had more variables.

So I want to know if there is a nicer way to apply values to functions such as these?

Upvotes: 3

Views: 1104

Answers (2)

Cat Plus Plus
Cat Plus Plus

Reputation: 129774

Either swap rnd_select arguments, or use flip rnd_select 6 =<< readNumbers.

Upvotes: 1

Daniel Fischer
Daniel Fischer

Reputation: 183878

Apart from defining the function such that the argument left out is the last argument, so that you can write

foobar = baz . foo 5 17 29 . bar

you can use a lambda to leave out arguments other than the last,

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

but for the case of just two arguments, flip is a nice alternative,

main = print =<< flip rnd_select 6 =<< readNumbers

Upvotes: 4

Related Questions