| ||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||
Description | ||||||||||||||||||||||||||||
Summary: Generic functions that apply a transformation at every location of one type in a value of a possibly different type. The functions everywhere and everywhere' have exactly the same type, but they apply the transformation in different fashions. everywhere uses bottom-up application while everywhere' uses a top-down approach. This may make a difference if you have recursive datatypes or use nested pattern matching in the higher-order function. These functions are very similar to others with the same names in the "Scrap Your Boilerplate" library (syb package). The SYB functions use rank-2 types, while the EMGM functions use a single class constraint. Compare the types of the following: -- SYB everywhere :: (forall a. Data a => a -> a) -> forall a. Data a => a -> a -- EMGM everywhere :: (Rep (Everywhere a) b) => (a -> a) -> b -> b | ||||||||||||||||||||||||||||
Synopsis | ||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||
Documentation | ||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||
Apply a transformation a -> a to values of type a within the argument of type b in a bottom-up manner. Values that do not have type a are passed through id. everywhere works by searching the datatype b for values that are the same type as the function argument type a. Here are some examples using the datatype declared in the documentation for Everywhere. ghci> let f t = case t of { Val i -> Val (i+(1::Int)); other -> other } ghci> everywhere f (Val (1::Int)) Val 2 ghci> everywhere f (Rec (Rec (Val (1::Int)))) Rec (Rec (Val 2)) ghci> let x = [Left 1, Right 'a', Left 2] :: [Either Int Char] ghci> everywhere (*(3::Int)) x [Left 3,Right 'a',Left 6] ghci> everywhere (\x -> x :: Float) x == x True Note the type annotations. Since numerical constants have the type Num a => a, you may need to give explicit types. Also, the function \x -> x has type a -> a, but we need to give it some non-polymorphic type here. By design, there is no connection that can be inferred between the value type and the function type. everywhere only works if there is an instance for the return type as described in the newtype Everywhere. | ||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||
Apply a transformation a -> a to values of type a within the argument of type b in a top-down manner. Values that do not have type a are passed through id. everywhere' is the same as everywhere with the exception of recursive datatypes. For example, compare the example used in the documentation for everywhere with the following. ghci> let f t = case t of { Val i -> Val (i+(1::Int)); other -> other } ghci> everywhere' f (Val (1::Int)) Val 2 ghci> everywhere' f (Rec (Rec (Val (1::Int)))) Rec (Rec (Val 1)) everywhere' only works if there is an instance for the return type as described in the newtype Everywhere'. | ||||||||||||||||||||||||||||
Produced by Haddock version 2.4.2 |