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?
Apart from defining the function such that the argument left out is the last argument, so that you can write
you can use a lambda to leave out arguments other than the last,
but for the case of just two arguments,
flipis a nice alternative,