3 ms·
Does an underscore at the end of the method signify anything in Haskell (eg replicateM_)?
by MaxGabriel 13y ago
Does an underscore at the end of the method signify anything in Haskell (eg replicateM_)?
- bstamour 13y agoTypically with monadic code, a function with an underscore at the end of its name discards it's effect. For example, the function mapM maps a function over a list, i.e. mapM :: Monad m => (a -> m b) -> [a] -> m [b] it returns the result of the computation. But sometimes you want to iterate over a list but discard the result (say you're printing elements.) mapM_ discards the result: mapM_ :: Monad m => (a -> m b) -> [a] -> m () where () denotes a kind of "null type". So if you want to store the results in a new list, you use mapM, but if you don't, and just want the "effects", you use mapM_. Here's an example of each, using the IO monad. If I have a list of numbers, and I want to iterate through each one and prompt the user for a multiplier, I would write the code like this: main = do let numbers = [1.. 10] numbers' <- forM numbers $ \n -> do putStrLn "Enter a multiplier" a <- getLine return $ n * (read a :: Int) where forM is just mapM with the arguments reversed to look more like a for-loop. Here I want the results of the computation, so I use forM. If, however I want to just print the numbers out, I'd use forM_ main = do let numbers = [1.. 10] forM_ numbers $ \n -> do putStrLn (show n)
- MaxGabriel 13y agoGreat explanation, thank you.
- judk 13y agoTo be clear (for readers, I know parent knows this), the return values of the effects are discarded. (The first sentence maybe should say "discard its results", not "discard it's effects"). The point is to make the (side-)effects happen (since non-strictness means the effects have to be forced, by calling `(>>=)` or similar) but not use the return value (which is how computations are usually forced in Haskell) And also, the effects happen in the order determined by the function forM_ or whoever, instead of in a hard-to-impossible-to-predict order of the pure non-monadic/non-effect computations defined by equations of function applications. (The M in fooM is for Monad, indicating that bind (f <<= x) is used instead of simple function application (f x) that is used in the "cousin" function foo. But that is just naming convention.)
- quchen 13y ago() is not null, it's the type that has only one value (think of it like Bool that's always True). Null (or C-void, which it is also often compared to) on the other hand stands for a lack of information and is more of a makeshift placeholder.
- groovy2shoes 13y agoThe semantics of (), a.k.a. unit, are effectively the same to those of null, and it can be useful to think of it that way. Both null and unit stand for lack of information and are placeholders. The difference is in the implementation details. http://en.wikipedia.org/wiki/Unit_type http://en.wikipedia.org/wiki/Unit_type