3 ms·
as a counterpoint, genericness can actually serve as a form of documentation. you can often infer a lot from just a signature, e.g: any :: (Functor f, Foldab
by uryga 6y ago
as a counterpoint, genericness can actually serve as a form of documentation. you can often infer a lot from just a signature, e.g:
any :: (Functor f, Foldable f) => (a -> Bool) -> f a -> Bool
tells me that `any` has to work across the whole collection `f a` (list/tree/whatever), because that's
how folding works, and that it will get the answer by calling the function on the collection's elements (the collection is a Functor, and the only thing you can do with one is `map` a function over it).
[of course this is assuming that `any` isn't implemented as `any _ _ = True`]
- Chris_Newton 6y agoThis advantage can be overstated and give a false sense of security, though. It’s true that for entirely generic functions, you can sometimes infer useful properties just from the type signature, but once you start getting any more specific types in there, all bets may be off. You said [of course this is assuming that `any` isn't implemented as `any _ _ = True`] but actually there are many more possibilities. For example, this function might return True if the provided data structure has exactly 5 elements, never using the provided (a -> Bool) function or mapping over anything.
- uryga 6y agoyou're right! but i think under normal circumstances it's fair to assume that the function actually uses all of its arguments. and i mean "uses" in a general handwavy sense, e.g. that it doesn't do `any f xs = length (fmap f xs)`, where `f` is technically used, but the results of applying `f` are instantly dropped.