* ...">

Using the "fmap-like" function for genus types *

Say we have a data type defined as

data A a = A' a deriving Show 

We have

A :: * -> *

Then we can make A an instance Functor:

instance Functor A where fmap f (A' x) = A' (f x)

This allows us to make a type value Aand use it fmapto apply the function to the wrapped value.

Prelude> let x = A' 1
Prelude> fmap (+1) x
A' 2

Now, if we determined Ahow

data A = A' Int deriving Show

Type A-

A :: *

Therefore, we cannot make an Ainstance of Functor -

instance Functor A where fmap f (A' x) = A' (f x)

<interactive>:4:18:
    Kind mis-match
    The first argument of `Functor' should have kind `* -> *',
    but `A' has kind `*'
    In the instance declaration for `Functor A'

My question is: is there a general way to apply a function to a wrapper value for data types of a view *using a data constructor that takes only one parameter (i.e., something similar to fmap)? It is quite easy to write a custom function:

Prelude> let myFmap f (A' x) = A' (f x)
Prelude> let x = A' 1
Prelude> myFmap (+1) x
A' 2

A Num:

instance Num A where (+) (A' x) (A' y) = A' (x + y) -- Ignoring the warnings
Prelude> A' 1 + A' 1 
A' 2

, , ?

+4
1

, , , , .

mono-traversable, MonoFunctor typeclass. A' :

type instance Element A' = Int

instance MonoFunctor a' where
  omap f (A' i) = A' (f i)

YMMV , a'map :: (Int -> Int) -> A' -> A' .

+10

Source: https://habr.com/ru/post/1612016/


All Articles