4 ms·
> ... in F#, something to the left of :: can never be anything other than the head of a list, and something to the right of :: can never be anything other than
by pash 14y ago
> ... in F#, something to the left of :: can never be anything other than the head of a list, and something to the right of :: can never be anything other than the tail of a list!
Yes, but the names you assign in a pattern get used outside the pattern. Presumably there will be an x/head or an xs/tail on the right side of the arrow in your example, and it's there that meaningful names help.
That said, I'm quite fond of the x:xs naming convention. It's particularly useful when you're doing something with two or more lists in the same scope, and you pattern-match to produce multiple heads and tails. For instance (Haskell syntax, as I don't know F#):
zip :: [a] -> [b] -> [(a, b)]
zip (x:xs) (y:ys) = x : y : zip xs ys
zip _ _ = []
This also illustrates when you might well disregard the trope of using "meaningful" names. The code above is polymorphic and will work for any types a and b, and for any values of those types, no matter what they represent. Functional programming really encourages this sort of generality. Yes, it's very much the case that, as the article's author wrote, "functional code tends to focus on applying generic transformations to 'things', and not that much on what the 'thing' might be."
But, if it helps to clarify what you're doing at the domain level, you can (and should) assign meaning through types and by renaming and adding restrictive type signatures to polymorphic code:
data Child = ...
data Chore = ...
type Assignment = (Child, Chore)
assign :: [Child] -> [Chore] -> [Assignment]
assign = zip
This not only helps readers understand what's going on, it also enlists the type-checker in helping to ensure you've, say, assigned chores only to your kids and not to your pets.
- pash 14y agoWhoops, I changed my example midway through and ended up with something screwy. The first case of the definition of zip above should of course read: zip (x:xs) (y:ys) = (x, y) : zip xs ys