3 ms·
> Many of the functions you'd write wouldn't care whether you're using a List or a Future, they would accept either. I can't imagine a situation where that wou
by sweeneyrod 7y ago
> Many of the functions you'd write wouldn't care whether you're using a List or a Future, they would accept either.
I can't imagine a situation where that would be true, except if you're writing a monad library. You could say that you might want to interchange a list of futures for a future of lists, but that's two interdependent things being swapped not one.
- Silhouette 7y agoYou've made at least two comments now mentioning this idea of interchange, but there's more to all of this than just that. The Haskell standard libraries are full of generic functions that can be applied to many practically useful types as long as those types provide certain basic guarantees. For example, there is a useful little function replicate :: Int -> a -> Seq a that allows us to build a sequence of n of some value. But what if we don't have a raw value, but instead some Applicative wrapper around it, and instead of just getting a sequence of individually wrapped values, we want that Applicative structure around the sequence? That is, we want some function f that will give us f 3 (Just 1) == Just (fromList [1, 1, 1]) but f 3 Nothing == Nothing with a Maybe, and f 3 (Right 'x') == Right (fromList "xxx") but f 3 (Left "error message") == Left "error message" with an Either, and similarly for any other Applicative. Well, such a function also exists in Data.Sequence: replicateA :: Applicative f => Int -> f a -> f (Seq a) Because it works with any Applicative, it can just as well work out all of the possible outcomes when we roll three dice: replicateA 3 [1, 2, 3, 4, 5, 6] or repeat the action of any Monad three times: replicateA 3 $ putStrLn "Hello, world!" or repeat whatever behaviour some Applicative you haven't even written yet will have next week. The rabbit hole gets as deep as you like. For example, we can easily compose a variety of other standard functions to count how many ways there are to reach each possible total in that dice example: map (head &&& length) $ group $ sort $ fmap sum $ replicateA 3 [1, 2, 3, 4, 5, 6] -- [(3,1),(4,3),(5,6),(6,10), ...] Many of these functions have quite general types, for example sum working on any Foldable and fmap working on any Functor. Because a list is an Applicative and any Applicative is also a Functor, and since the individual results of the replicateA will be Seqs and any Seq is also a Foldable, everything works fine, and the list structure we started with is preserved all the way through.