Вы можете объявить экземпляр класса Functor
. Это стандартный класс для типов данных, которые позволяют отображать функцию. Обратите внимание, насколько тип fmap
похож на тип mapT
:
class Functor f where
fmap :: (a -> b) -> f a -> f b
Давайте предположим, что ваше дерево определено как
data Tree a = Node (Tree a) (Tree a) | Leaf a
deriving (Show)
Затем вы можете объявить экземпляр Functor
следующим образом:
instance Functor Tree where
fmap f (Node l r) = Node (fmap f l) (fmap f r)
fmap f (Leaf x) = Leaf (f x)
Вот как это можно использовать:
main = do
let t = Node (Node (Leaf 1) (Leaf 2)) (Leaf 3)
let f = show . (2^)
putStrLn $ "Old Tree: " ++ (show t)
putStrLn $ "New Tree: " ++ (show . fmap f $ t)
Выход:
Old Tree: Node (Node (Leaf 1) (Leaf 2)) (Leaf 3)
New Tree: Node (Node (Leaf "2") (Leaf "4")) (Leaf "8")
Вы также можете определить для удобства:
mapT = fmap
Конечно, вы можете делать это без классов типов, но это делает код более читабельным для других, если вы используете стандартные функции (все знают обычное поведение fmap
).