-
Notifications
You must be signed in to change notification settings - Fork 89
/
Copy pathFunctor.purs
106 lines (90 loc) · 2.7 KB
/
Functor.purs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
module Data.Functor
( class Functor
, map
, (<$>)
, mapFlipped
, (<#>)
, void
, voidRight
, (<$)
, voidLeft
, ($>)
, flap
, (<@>)
) where
import Data.Function (const, compose)
import Data.Unit (Unit, unit)
import Type.Proxy (Proxy(..))
-- | A `Functor` is a type constructor which supports a mapping operation
-- | `map`.
-- |
-- | `map` can be used to turn functions `a -> b` into functions
-- | `f a -> f b` whose argument and return types use the type constructor `f`
-- | to represent some computational context.
-- |
-- | Instances must satisfy the following laws:
-- |
-- | - Identity: `map identity = identity`
-- | - Composition: `map (f <<< g) = map f <<< map g`
class Functor f where
map :: forall a b. (a -> b) -> f a -> f b
infixl 4 map as <$>
-- | `mapFlipped` is `map` with its arguments reversed. For example:
-- |
-- | ```purescript
-- | [1, 2, 3] <#> \n -> n * n
-- | ```
mapFlipped :: forall f a b. Functor f => f a -> (a -> b) -> f b
mapFlipped fa f = f <$> fa
infixl 1 mapFlipped as <#>
instance functorFn :: Functor ((->) r) where
map = compose
instance functorArray :: Functor Array where
map = arrayMap
instance functorProxy :: Functor Proxy where
map _ _ = Proxy
foreign import arrayMap :: forall a b. (a -> b) -> Array a -> Array b
-- | The `void` function is used to ignore the type wrapped by a
-- | [`Functor`](#functor), replacing it with `Unit` and keeping only the type
-- | information provided by the type constructor itself.
-- |
-- | `void` is often useful when using `do` notation to change the return type
-- | of a monadic computation:
-- |
-- | ```purescript
-- | main = forE 1 10 \n -> void do
-- | print n
-- | print (n * n)
-- | ```
void :: forall f a. Functor f => f a -> f Unit
void = map (const unit)
-- | Ignore the return value of a computation, using the specified return value
-- | instead.
voidRight :: forall f a b. Functor f => a -> f b -> f a
voidRight x = map (const x)
infixl 4 voidRight as <$
-- | A version of `voidRight` with its arguments flipped.
voidLeft :: forall f a b. Functor f => f a -> b -> f b
voidLeft f x = const x <$> f
infixl 4 voidLeft as $>
-- | Apply a value in a computational context to a value in no context.
-- |
-- | Generalizes `flip`.
-- |
-- | ```purescript
-- | longEnough :: String -> Bool
-- | hasSymbol :: String -> Bool
-- | hasDigit :: String -> Bool
-- | password :: String
-- |
-- | validate :: String -> Array Bool
-- | validate = flap [longEnough, hasSymbol, hasDigit]
-- | ```
-- |
-- | ```purescript
-- | flap (-) 3 4 == 1
-- | threeve <$> Just 1 <@> 'a' <*> Just true == Just (threeve 1 'a' true)
-- | ```
flap :: forall f a b. Functor f => f (a -> b) -> a -> f b
flap ff x = map (\f -> f x) ff
infixl 4 flap as <@>