4 ms·
A simpler example would be a basic list operator, given a method you can guess what it does. [a] -> a That takes a list (brackets denote a linked list) an
by Guvante 13y ago
A simpler example would be a basic list operator, given a method you can guess what it does.
[a] -> a
That takes a list (brackets denote a linked list) and returns a single item. There is a small list of things that this could be. It can't filter or order in any way, since there are no restrictions or functions provided, it can't aggregate for the same reason, that leaves either the first item or the last item.
[Yep head and last](http://www.haskell.org/hoogle/?hoogle=%5Ba%5D+-%3E+a http://www.haskell.org/hoogle/?hoogle=%5Ba%5D+-%3E+a)
Looking at that list we can see some other alternatives that I mentioned
foldl1 :: (a -> a -> a) -> [a] -> a --Aggregation
maximumBy :: (a -> a -> Ordering) -> [a] -> a --Ordering
maximum :: Ord a => [a] -> a
(!!) :: [a] -> Int -> a --Indexing
sum :: Num a => [a] -> a --Aggregating
product :: Num a => [a] -> a
And if followed along, you will notice all of his implementation points were straightforward.
Note that all of this assumes you have very well written APIs that follow this chain of logic, otherwise you can write things like this.
second :: [a] -> a
second _:i:_ = i
It compiles (or would with the default case added) but is rather odd and would throw off this line of reasoning. Similarly by abusing unsafe methods you can do crazy things.
- nandemo 13y agoYour function second is no worse than head or last. I think you chose a difficult example. [a]->[a] or a->a would be simpler, if a bit boring.
- Guvante 13y agoI dunno, I like second being a bad choice, the number of times it is useful are very few. `!! 2` is much more straightforward. In contrast `last` is impossible to do that way and `head` is part of the underlying data structure (as in it is a linked list, so has head and tail) so is a gimme.
- jlarocco 13y ago> It can't filter or order in any way, since there are no restrictions or functions provided, it can't aggregate for the same reason, that leaves either the first item or the last item. That doesn't logically follow. Technically it can return any item in the list. Without some kind of documentation there's no way to know. Saying "you can guess what it does" doesn't buy me anything over any other language. I can guess what a function does in C or C++, too, and in my experience I'll guess right in C and C++ more often than I will in Haskell.
- Guvante 13y ago> Technically it can return any item in the list But that is all it can return. By looking at the name I know with 100% certainty what it is. > I can guess what a function does in C or C++, too Never without the name. Too few functions are actually pure and the difference in a pure signature and a non-pure one doesn't exist. Heck if it is C or C++ it could cast all the void* to int* and find the first one that is non-null and points to a positive value.
- dragonwriter 13y ago> [a] -> a > That takes a list (brackets denote a linked list) and returns a single item. There is a small list of things that this could be. It can't filter or order in any way, since there are no restrictions or functions provided, it can't aggregate for the same reason, that leaves either the first item or the last item. Assuming that lists can be empty, it can't be the first item or last item either, as either of those (or the second, or third, etc.) would have to be [a] -> Maybe a Haskell doesn't actually do this, but (while there may be pragmatic reasons to do this and yet have them work on a type that isn't constrained to non-empty lists), its kind of a failure in the logic of types, which makes head (and last, etc.) subject to crashing. But if you pretend that you can use type based logic and what is possible to guarantee based on the type signature to infer semantics of returned values, then you have to really follow the logic alone -- if you can start to accept that there could be unstated assumptions of the type Haskell actually makes, then you open up lots of other possibilities based on which specific unstated assumptions that aren't implicit in the types involved are made.