4 ms·
I mean the 'lowers' function from the linked post, which counts the lowercase characters of its input. In this case the apl function returns an array of rank o
by moonchild 5y ago
I mean the 'lowers' function from the linked post, which counts the lowercase characters of its input. In this case the apl function returns an array of rank one less than its input, where each item is the number of lowercase characters at the given position along the reduced axis.
I don't think this can be expressed using fmap. (I'm not sure what <$> is, but judging from [0] it seems to be syntactic sugar for fmap?) You would at least the more powerful 'reduce' (or some analogue thereof), and I'm not even sure if that would be sufficient to properly express the rank operator.
0. https://wiki.haskell.org/Functor#Related_Functions https://wiki.haskell.org/Functor#Related_Functions
EDIT: the problem with the rank operator is ensuring the array remains rectangular. (I know haskell lists are not rectangular; imagining a type which was.) APL punts on this by being dynamically typed, but you would have to solve that problem somehow. 'Reshape' suffers somewhat the same problem, and I'm not sure it can be typed sensibly.
- dwohnitmok 5y agoAh I see. Right so the 0th rank version you've presented here could be written as -- Assume countLower exists and is [Char] -> Int lowers : Functor f => f [Char] -> f Int lowers xs = countLower <$> xs -- Also: lowers = fmap countLower This `lowers` works for rank 0 across arbitrary rank collections so you can have as many nestings you'd like. Now if you want to vary the rank at compile time, that is possible by generalizing `countLower` away from a concrete list and instead to something like `Traversable`. The issue as you point out is if you want to vary the rank at runtime, which is easy to do in APL and other array-based programming languages, and which is quite difficult to do in a way that plays well with Haskell's type system (you could eject and instead use dynamic typing in Haskell instead, but that is probably going to look quite different from the rest of your Haskell code). And this indeed is part of the infelicities I was talking about. To really type this well you need dependent types, which you can kind of do in Haskell, but it rapidly becomes very messy.