Stuff that wasn’t completely obvious to me while I learned Haskell pt 0.01
There are no nullary functions in Haskell. There are nullary functions in the untyped lambda calculus, but Haskell is based off a (the?) typed lambda calculus, and so, not everything is a function.
The way you read types is, the thing after the last ” -> ” is the output, and everything preceding it is (are) input(s). “[String] -> [String]” is read as “a function that takes as inputs lists of strings and outputs lists of strings”. “[String] -> Int -> [String]” is read as “a function that takes as inputs a list of strings, and an Int, and outputs a list of strings “. “[String] -> ([String] -> Int) -> String” is read as “a function that takes as inputs, a list of strings, and, a function from a list of strings to Ints, and outputs a string”.
With filter, it takes as inputs functions and lists, and outputs lists. But the functions must be functions from concrete types, to bools. They’re predicates, like “is red” or “is greater than 50 million” or “has as a factor the number 5”. There aren’t many of these around in the standard prelude. But you don’t want to have to define an entire function for what’s likely to be the one thing you’re trying to filter for, so you use a lambda abstraction, filter (\x -> x > 2) xs, or an operator section, filter (>100) xs.
Currying combined with Polymorphic Types can be surprising. Don’t get caught off guard when learning a function, which has type ” [a] -> [a] “, and the resource you’re using only uses examples where the ” a ” in ” [a] ” is something like ‘Int’ or ‘String’…it can be anything, including functions themselves…i.e. it could operate on a list of functions, and return a list of functions. Currying makes for even more surprises when, in defining a new function using that old one, someone curries the first argument…then you’re left with a list of functions. I \*think\* that lazy evaluation makes this possible, but I can’t be sure.