operator()
is called a functor. Now take the Standard ML . In ML, functors map structures to structures. Now Haskell . In Haskell, functors are simply a homomorphism over categories. And in Prolog, a functor means an atom at the beginning of a structure. They all differ. Let's take a closer look at each of them.operator()
defined. If you define an operator()
for a C ++ class, then you get an object that acts as a function, but can also store a state. For example, #include <iostream> #include <string> class SimpleFunctor { std::string name_; public: SimpleFunctor(const char *name) : name_(name) {} void operator()() { std::cout << "Oh, hello, " << name_ << endl; } }; int main() { SimpleFunctor sf("catonmat"); sf(); // "Oh, hello, catonmat" }
sf()
in the function main
, although sf
is an object. This is because operator()
defined for it in the SimpleFunctor
class.for_each
. #include <algorithm> #include <iostream> #include <list> class EvenOddFunctor { int even_; int odd_; public: EvenOddFunctor() : even_(0), odd_(0) {} void operator()(int x) { if (x%2 == 0) even_ += x; else odd_ += x; } int even_sum() const { return even_; } int odd_sum() const { return odd_; } }; int main() { EvenOddFunctor evenodd; int my_list[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; evenodd = std::for_each(my_list, my_list+sizeof(my_list)/sizeof(my_list[0]), evenodd); std::cout << " : " << evenodd.even_sum() << "\n"; std::cout << " : " << evenodd.odd_sum() << std::endl; // : // : 30 // : 25 }
EvenOddFunctor
instance EvenOddFunctor
passed to for_each
. for_each is iterated over each element in my_list and calls a functor. After that, it returns a copy of the evenodd
functor, which contains the sum of even and odd elements.perform
. In ML, you must first set the signature for the plugins,signature Plugin =
sig
val perform : unit -> unit
end ;
LoudPlugin
and SilentPlugin
. Implementation is done through structuresstructure LoudPlugin :> Plugin =
struct
fun perform ( ) = print "PERFORM A JOB VOLUME! \ n"
end ;
structure SilentPlugin :> Plugin =
struct
fun perform ( ) = print "do the task quietly \ n"
end ;
Plugin
is required as an argument,functor Performer ( P : Plugin ) =
struct
fun job ( ) = P. perform ( )
end ;
Plugin
as an argument P
and uses it for the job
function, which calls the perform
function on the plugin P
Performer
functor. Remember that the functor returns a structure,structure LoudPerformer = Performer ( LoudPlugin ) ;
structure SilentPerformer = Performer ( SilentPlugin ) ;
LoudPerformer . job ( ) ;
SilentPerformer . job ( ) ;
We carry out the task is loud! perform the task quietly
class Functor f where
fmap :: ( a -> b ) -> f a -> f b
Functor
defined not on types, but on a constructor of type f
. This means Functor
is what implements the fmap
function, which accepts a function (accepting type a
and returning type b
) and a value of type fa
(type constructed from a constructor of type f
, applied to type a
) and returns a value of type fb
.fmap
as a function that applies an operation to every element in a container.map
function, which applies a function to each element in the list.Prelude> map (+1) [1,2,3,4,5]
[2,3,4,5,6]
Functor
function of fmap
is just a map
and the constructor of type f
is []
- the constructor of the list type. Therefore, Functor
, for example, for lists is defined asinstance functor [ ] where
fmap = map
fmap
instead of map
,Prelude> fmap (+1) [1,2,3,4,5]
[2,3,4,5,6]
fmap
rules:fmap id = id
fmap (g. h) = fmap g. fmap h
fmap
function to the tree values, keeping the tree structure.data Tree a = Node ( Tree a ) ( Tree a )
| Leafa
deriving show
Tree
(tree) is either a Node
(branch) of two Tree
(left and right branches) or Leaf
(leaf). The deriving Show
expression allows us to inspect the tree through the show function.Functor
above Tree
instance functor tree where
fmap g ( Leaf v ) = Leaf ( g v )
fmap g ( Node l r ) = Node ( fmap g l ) ( fmap g r )
fmap
of g
over Leaf
with a value of v
is just Leaf
of g
applied to v
. And fmap
from g
over Node
with the left branch l
and right r
is just the Node
from fmap
applied to the values ​​of the left and right branch.fmap
works with trees. Construct a tree with string ( String
) leaves and apply the length function above them to find out the length of each sheet.Prelude> let tree = (Node (Node (Leaf "hello") (Leaf "foo")) (Leaf "baar"))
Prelude> fmap length tree
Node (Node (Leaf 5) (Leaf 3)) (Leaf 4)
* / \ / \ * "baar" / \ / \ / \ / \ "hello" "foo"
length
mapping above it gives us* / \ / \ * four / \ / \ / \ / \ 5 3
fmap
does - displays (in the original - raises ) a function from the “normal world” to the “ f
world”.? - likes ( mary , pizza )
likes
.functor
. It returns the arity and structure functor. For example,? - functor ( likes ( mary , pizza ) , Functor , Arity ) .
Functor = likes
Arity = 2
Source: https://habr.com/ru/post/125995/
All Articles