Why is this Functor instance incorrect? - haskell

I've written this code:
newtype Pixel a = Pixel (a,a,a) deriving (Show)
instance Functor [Pixel Int] where
fmap f [] = []
fmap f [Pixel(a,b,c)] = [Pixel(f a, b, c)]
I want the functor to apply to the first element in the Pixel type, but I keep getting this error:
New.hs:17:18: error:
• Expecting one fewer arguments to ‘[Pixel Int]’
Expected kind ‘* -> *’, but ‘[Pixel Int]’ has kind ‘*’
• In the first argument of ‘Functor’, namely ‘[Pixel Int]’
In the instance declaration for ‘Functor [Pixel Int]’
I'm pretty lost on this issue, is there any way to apply a functor on an entire list? Or do I need to set up a functor for an individual Pixel type and then iterate through a list?

From what I understand, you're given a list of pixels and you want to change the first component (i.e. the red component) of every pixel. Hence, you want the following function:
changeAllPixels :: [Pixel Int] -> [Pixel Int]
Q: How do we change every element of a list? A: We use map:
changeAllPixels = map changeOnePixel
changeOnePixel :: Pixel Int -> Pixel Int
We only want to change the red component. Hence, we have:
changeOnePixel = changeRedComponent doSomething
changeRedComponent :: (a -> a) -> Pixel a -> Pixel a
changeRedComponent f (Pixel (r, g, b)) = Pixel (f r, g, b)
doSomething :: Int -> Int
Now you only need to implement doSomething. For example, if you want to invert the red component then you could implement doSomething as follows:
doSomething x = 255 - x
Note that we didn't make Pixel an instance of Functor. This is because we only want to change the red component and leave the green and blue components alone. We did however use map which is the fmap for lists.
I think the biggest problem you have is that you don't understand functors well. You should probably spend some time getting acquainted with them.

Actually, [Pixel Int] already has an instance of Functor because it is a list []. The Functor instance for list [] is defined in GHC base (it uses the definition of map). Now you just need a function that can be applied to each element of that list.
fmap show [(Pixel 0 0 0),(Pixel 1 0 0), (Pixel 0 1 0)]
Functor is generally defined for some container type. It takes a function and applies it to the contents of the container. Then when you call fmap on a container that has an instance of Functor, the compiler will check that the function can be applied to the elements of that container.
If you are still confused about Functors, I recommend this tutorial: Functors, Applicatives, And Monads In Pictures.

Your syntax is a bit off, fmap applies a function to a data type and you tell it how. To change values for a list of pixels you would need to map (fmap f) over the list.
Give this implementation a try.
instance Functor Pixel where
fmap f (Pixel (a,b,c)) = Pixel (f a, b, c)
Edit this won't work because a,b,c need to be of the same type and functors allow functions of type a->b.
As #AlexisKing commented you should use fmap, but instead write a function like mapPixelFirst :: (a -> a) -> Pixel a -> Pixel a. Then map this function over user list, don't use fmap.

Related

Hidden forall quantified types in ReifiedTraversal

This question really is more generic, since while I was asking it I found out how to fix it in this particular case (even though I don't like it) but I'll phrase it in my particular context.
Context:
I'm using the lens library and I found it particularly useful to provide functionality for "adding" traversals (conceptually, a traversal that traverses all the elements in both original traversals). I did not find a default implementation so I did it using Monoid. In order to be able to implement an instance, I had to use the ReifiedTraversal wrapper, which I assume is in the library precisely for this purpose:
-- Adding traversals
add_traversals :: Semigroup t => Traversal s t a b -> Traversal s t a b -> Traversal s t a b
add_traversals t1 t2 f s = liftA2 (<>) (t1 f s) (t2 f s)
instance Semigroup t => Semigroup (ReifiedTraversal s t a b) where
a1 <> a2 = Traversal (add_traversals (runTraversal a1) (runTraversal a2))
instance Semigroup s => Monoid (ReifiedTraversal' s a) where
mempty = Traversal (\_ -> pure . id)
The immediate application I want to extract from this is being able to provide a traversal for a specified set of indices in a list. Therefore, the underlying semigroup is [] and so is the underlying Traversable. First, I implemented a lens for an individual index in a list:
lens_idx :: Int -> Lens' [a] a
lens_idx _ f [] = error "No such index in the list"
lens_idx 0 f (x:xs) = fmap (\rx -> rx:xs) (f x)
lens_idx n f (x:xs) = fmap (\rxs -> x:rxs) (lens_idx (n-1) f xs)
All that remains to be done is to combine these two things, ideally to implement a function traversal_idxs :: [Int] -> Traversal' [a] a
Problem:
I get type checking errors when I try to use this. I know it has to do with the fact that Traversal is a type that includes a constrained forall quantifier in its definition. In order to be able to use the Monoid instance, I need to first reify the lenses provided by lens_idx (which are, of course, also traversals). I try to do this by doing:
r_lens_idx :: Int -> ReifiedTraversal' [a] a
r_lens_idx = Traversal . lens_idx
But this fails with two errors (two versions of the same error really):
Couldn't match type ‘f’ with ‘f0’...
Ambiguous type variable ‘f0’ arising from a use of ‘lens_idx’
prevents the constraint ‘(Functor f0)’ from being solved...
I understand this has to do with the hidden forall f. Functor f => in the Traversal definition. While writing this, I realized that the following does work:
r_lens_idx :: Int -> ReifiedTraversal' [a] a
r_lens_idx idx = Traversal (lens_idx idx)
So, by giving it the parameter it can make the f explicit to itself and then it can work with it. However, this feels extremely ad-hoc. Specially because originally I was trying to build this r_lens_idx inline in a where clause in the definition of the traversal_idxs function (in fact... on a function defining this function inline because I'm not really going to use it that often).
So, sure, I guess I can always use lambda abstraction, but... is this really the right way to deal with this? It feels like a hack, or rather, that the original error is an oversight by the type-checker.
The "adding" of traversals that you want was added in the most recent lens release, you can find it under the name adjoin. Note that it is unsound to use if your traversals overlap at all.
I am replying to my own question, although it is only pointing out that what I was trying to do with traversals was not actually possible in that shape and how I overcame it. There is still the underlying problem of the hidden forall quantified variables and how is it possible that lambda abstraction can make code that does not type check suddenly type check (or rather, why it did not type check to start with).
It turns out my implementation of Monoid for Traversal was deeply flawed. I realized when I started debugging it. For instance, I was trying to combine a list of indices, and a function that would return a lens for each index, mapping to that index in a list, to a traversal that would map to exactly those indices. That is possible, but it relies on the fact that List is a Monad, instead of just using the Applicative structure.
The function that I had written originally for add_traversal used only the Applicative structure, but instead of mapping to those indices in the list, it would duplicate the list for each index, concatenating them, each version of the list having applied its lens.
When trying to fix it, I realized I needed to use bind to implement what I really wanted, and then I stumbled upon this: https://www.reddit.com/r/haskell/comments/4tfao3/monadic_traversals/
So the answer was clear: I can do what I want, but it's not a Monoid over Traversal, but instead a Monoid over MTraversal. It still serves my purposes perfectly.
This is the resulting code for that:
-- Monadic traversals: Traversals that only work with monads, but they allow other things that rely on the fact they only need to work with monads, like sum.
type MTraversal s t a b = forall m. Monad m => (a -> m b) -> s -> m t
type MTraversal' s a = MTraversal s s a a
newtype ReifiedMTraversal s t a b = MTraversal {runMTraversal :: MTraversal s t a b}
type ReifiedMTraversal' s a = ReifiedMTraversal s s a a
-- Adding mtraversals
add_mtraversals :: Semigroup t => MTraversal r t a b -> MTraversal s r a b -> MTraversal s t a b
add_mtraversals t1 t2 f s = (t2 f s) >>= (t1 f)
instance Semigroup s => Semigroup (ReifiedMTraversal' s a) where
a1 <> a2 = MTraversal (add_mtraversals (runMTraversal a1) (runMTraversal a2))
instance Semigroup s => Monoid (ReifiedMTraversal' s a) where
mempty = MTraversal (\_ -> return . id)
Note that MTraversal is still a LensLike and an ASetter, so you can use many operators from the lens package, like .~.
As I mentioned, though, I still have to use lambda abstraction when using this for my purposes due to the forall quantifier being in an uncomfortable place, and I'd love if someone could clarify what the heck is up with the type checker in that regard.

How do I get a handle on deep stacks of functors in Haskell?

Now and then I find myself mapping over a deep stack of functors, e.g. a parser for some collection of optional values:
-- parse a rectangular block of characters to a map of
-- coordinate to the character, or Nothing for whitespace
parseRectangle :: Parser (Map (Int, Int) (Maybe Char))
data Class = Letter | Digit | Other
classify :: Char -> Class
parseClassifiedRectangle :: Parser (Map (Int, Int) (Maybe Class))
parseClassifiedRectangle = fmap (fmap (fmap classify)) parseRectangle
What are some good ways around the nested fmaps? Oftentimes it's not as clear as here, and I end up adding fmaps until the code type checks. Simple code ends up as a mess of fmap boilerplate, where what I really want to express is "lift this function to the appropriate depth and apply it to the contained type".
Some ideas, none of which I've found particularly satisfactory so far:
define fmap2 :: (Functor f, Functor g) => (a -> b) -> g (f a) -> g (f b) and friends
define concrete helpers, like mapMaybeMap :: (a -> b) -> Map k (Maybe a) -> Map k (Maybe b)
introduce newtype wrappers for the functor stack, and make those instances of Functor, like newtype MaybeMapParser a = Parser (Map (Int, Int) (Maybe a))
Do others run into this problem in large codebases? Is it even a problem? How do you deal with it?
Let me break the ice on this interesting question that people seem shy about answering. This question probably comes down to more of a matter of style than anything, hence the lack of answers.
My approach would be something like the following:
parseClassifiedRectangle :: Parser (Map (Int, Int) (Maybe Class))
parseClassifiedRectangle = doClassify <$> parseRectangle
where
doClassify = Map.map (fmap classify)
I try to use <$> for the top level Functor, and save fmap for interior functors; although that doesn't always work too well in practice.
I've used a local named binding. But even if doClassify were left as f it sometimes helps clarify a high level view of whats happening: "on the parsed value we are doing a thing, see below for what thing does." I don't know what the efficiency concerns are for making a binding.
I've also used the specific instance of fmap for the Map instance. This helps orient me within the stack and gives a signpost for the final fmap.
Hope this helps.

Does exporting type constructors make a difference?

Let's say I have an internal data type, T a, that is used in the signature of exported functions:
module A (f, g) where
newtype T a = MkT { unT :: (Int, a) }
deriving (Functor, Show, Read) -- for internal use
f :: a -> IO (T a)
f a = fmap (\i -> T (i, a)) randomIO
g :: T a -> a
g = snd . unT
What is the effect of not exporting the type constructor T? Does it prevent consumers from meddling with values of type T a? In other words, is there a difference between the export list (f, g) and (f, g, T()) here?
Prevented
The first thing a consumer will see is that the type doesn't appear in Haddock documentation. In the documentation for f and g, the type Twill not be hyperlinked like an exported type. This may prevent a casual reader from discovering T's class instances.
More importantly, a consumer cannot doing anything with T at the type level. Anything that requires writing a type will be impossible. For instance, a consumer cannot write new class instances involving T, or include T in a type family. (I don't think there's a way around this...)
At the value level, however, the main limitation is that a consumer cannot write a type annotation including T:
> :t (f . read) :: Read b => String -> IO (A.T b)
<interactive>:1:39: Not in scope: type constructor or class `A.T'
Not prevented
The restriction on type signatures is not as significant a limitation as it appears. The compiler can still infer such a type:
> :t f . read
f . read :: Read b => String -> IO (A.T b)
Any value expression within the inferrable subset of Haskell may therefore be expressed regardless of the availability of the type constructor T. If, like me, you're addicted to ScopedTypeVariables and extensive annotations, you may be a little surprised by the definition of unT' below.
Furthermore, because typeclass instances have global scope, a consumer can use any available class functions without additional limitation. Depending on the classes involved, this may allow significant manipulation of values of the unexposed type. With classes like Functor, a consumer can also freely manipulate type parameters, because there's an available function of type T a -> T b.
In the example of T, deriving Show of course exposes the "internal" Int, and gives a consumer enough information to hackishly implement unT:
-- :: (Show a, Read a) => T a -> (Int, a)
unT' = (read . strip . show') `asTypeOf` (mkPair . g)
where
strip = reverse . drop 1 . reverse . drop 9
-- :: T a -> String
show' = show `asTypeOf` (mkString . g)
mkPair :: t -> (Int, t)
mkPair = undefined
mkString :: t -> String
mkString = undefined
> :t unT'
unT' :: (Show b, Read b) => A.T b -> (Int, b)
> x <- f "x"
> unT' x
(-29353, "x")
Implementing mkT' with the Read instance is left as an exercise.
Deriving something like Generic will completely explode any idea of containment, but you'd probably expect that.
Prevented?
In the corners of Haskell where type signatures are necessary or where asTypeOf-style tricks don't work, I guess not exporting the type constructor could actually prevent a consumer from doing something they could with the export list (f, g, T()).
Recommendation
Export all type constructors that are used in the type of any value you export. Here, go ahead and include T() in your export list. Leaving it out doesn't accomplish anything other than muddying the documentation. If you want to expose an purely abstract immutable type, use a newtype with a hidden constructor and no class instances.

Generalizing mapAndUnzip

I'm looking for an easy way to write the function
mapAndUnzip :: (Functor f) => (a -> (b,c)) -> f a -> (f b, f c)
I'm not entirely convinced that Functor is a strong enough constraint, but I'll use it for concreteness. I want to be able to apply this function when f has type (to name a few) [], Data.Vector.Unboxed.Vector, and my own wrapper types around [a] and Vector a. (Other possible types include Array, Repa vectors, etc.)
My key requirement is that I should not need a constraint like (Unbox (b,c)), only (Unbox b,Unbox c). Subrequirement: compute the function only once for each input element.
I see a way to do this for Vector by building two mutable vectors as I map over the input, but I'm hoping there's a better way than making a new class and my own instances for different types. The list-specific way that GHC.Util defines mapAndUnzip makes me think a generic solution might not be possible, but I figured I'd get a second opinion before hacking my own solution.
Functor is enough, you can do:
(EDIT: Compute g only once)
mapAndUnzip g fa = (fmap fst fbc, fmap snd fbc)
where
fbc = fmap g fa

Applicative without a functor

I have a type Image which is basically an c-array of floats. It is easy to create functions
such as map :: (Float -> Float) -> Image -> Image, or zipWith :: (Float -> Float -> Float) -> Image -> Image -> Image.
However, I have a feeling that it would also be possible to provide something that looks like an applicative instance on top of these functions, allowing more flexible pixel level manipulations like ((+) <$> image1 <*> image2) or ((\x y z -> (x+y)/z) <$> i1 <*> i2 <*> i3). However, the naive approach fails, since Image type cannot contain things other than floats, making it impossible to implement fmap as such.
How could this be implemented?
Reading the comments, I'm a little worried that size is under the carpet here. Is there a sensible behaviour when sizes mismatch?
Meanwhile, there may be something you can sensibly do along the following lines. Even if your arrays aren't easy to make polymorphic, you can make an Applicative instance like this.
data ArrayLike x = MkAL {sizeOf :: Int, eltOf :: Int -> x}
instance Applicative ArrayLike where
pure x = MkAL maxBound (pure x)
MkAL i f <*> MkAL j g = MkAL (min i j) (f <*> g)
(Enthusiasts will note that I've taken the product of the (Int ->) applicative with that induced by the (maxBound, min) monoid.)
Could you make a clean correspondence
imAL :: Image -> ArrayLike Float
alIm :: ArrayLike Float -> Image
by projection and tabulation? If so, you can write code like this.
alIm $ (f <$> imAL a1 <*> ... <*> imAL an)
Moreover, if you then want to wrap that pattern up as an overloaded operator,
imapp :: (Float -> ... -> Float) -> (Image -> ... -> Image)
it's a standard exercise in typeclass programming! (Ask if you need more of a hint.)
The crucial point, though, is that the wrapping strategy means you don't need to monkey with your array structures in order to put functional superstructure on top.
How would you expect to perform operations on pixels in an image? That is, for ((+) <$> image1 <*> image2), would you want to perform all the operations in Haskell and construct a new resulting image, or would you have to call C functions to do all the processing?
If it's the former, pigworker's answer is the approach I would take.
If instead it's required that all image manipulations be handled via C, how about creating a small DSL to represent the operations?
You'll get a much more compositional Image type if you generalize the "pixel" type from Float and extend from finite & discrete domain (arrays) to infinite & continuous domain.
As a demonstration of these generalizations, see the paper Functional Images and a corresponding gallery of (finite samplings of) example images.
As a result, you get instances of Monoid, Functor, Applicative, Monad, and Comonad.
Moreover, the meanings of these instances are entirely determined by the corresponding instances for functions, satisfying the principle of semantic type class morphisms, as described in the paper Denotational design with type class morphisms.
Section 13.2 of that paper briefly describes imagery.

Resources