@@ -19,9 +19,8 @@ module Ntp.Util
19
19
, createAndBindSock
20
20
, udpLocalAddresses
21
21
22
- , EitherOrBoth (.. )
23
- , foldEitherOrBoth
24
- , pairEitherOrBoth
22
+ , foldThese
23
+ , pairThese
25
24
26
25
, ntpTrace
27
26
, logDebug
@@ -41,6 +40,7 @@ import Data.List (find)
41
40
import Data.Semigroup (First (.. ), Last (.. ), Option (.. ),
42
41
Semigroup (.. ))
43
42
import Data.Text (Text )
43
+ import Data.These (These (.. ))
44
44
import Formatting (sformat , shown , (%) )
45
45
import Network.Socket (AddrInfo ,
46
46
AddrInfoFlag (AI_ADDRCONFIG , AI_PASSIVE ),
@@ -99,70 +99,41 @@ getAddrFamily (WithIPv6 _) = IPv6
99
99
getAddrFamily (WithIPv4 _) = IPv4
100
100
101
101
-- |
102
- -- Keep either of the two types or both.
103
- data EitherOrBoth a b
104
- = EBFirst ! a
105
- | EBSecond ! b
106
- | EBBoth ! a ! b
107
- deriving (Show , Eq , Ord )
108
-
109
- instance Bifunctor EitherOrBoth where
110
- bimap f _ (EBFirst a) = EBFirst $ f a
111
- bimap _ g (EBSecond b) = EBSecond $ g b
112
- bimap f g (EBBoth a b) = EBBoth (f a) (g b)
113
-
114
- -- |
115
- -- @'EitehrOrBoth'@ is an (associative) semigroup whenever both @a@ and @b@ are.
116
- instance (Semigroup a , Semigroup b ) => Semigroup (EitherOrBoth a b ) where
117
-
118
- EBFirst a <> EBFirst a' = EBFirst (a <> a')
119
- EBFirst a <> EBSecond b = EBBoth a b
120
- EBFirst a <> EBBoth a' b = EBBoth (a <> a') b
121
-
122
- EBSecond b <> EBFirst a = EBBoth a b
123
- EBSecond b <> EBSecond b' = EBSecond (b <> b')
124
- EBSecond b <> EBBoth a b' = EBBoth a (b <> b')
125
-
126
- EBBoth a b <> EBFirst a' = EBBoth (a <> a') b
127
- EBBoth a b <> EBSecond b' = EBBoth a (b <> b')
128
- EBBoth a b <> EBBoth a' b' = EBBoth (a <> a') (b <> b')
129
-
130
- -- |
131
- -- Note that the composition of `foldEitherOrBoth . bimap f g` is a proof that
132
- -- @'EitherOrBoth a b@ is the [free
102
+ -- Note that the composition of `foldThese . bimap f g` is a proof that
103
+ -- @'These a b@ is the [free
133
104
-- product](https://en.wikipedia.org/wiki/Free_product) of two semigroups @a@
134
105
-- and @b@.
135
- foldEitherOrBoth
106
+ foldThese
136
107
:: Semigroup a
137
- => EitherOrBoth a a
108
+ => These a a
138
109
-> a
139
- foldEitherOrBoth ( EBFirst a) = a
140
- foldEitherOrBoth ( EBSecond a) = a
141
- foldEitherOrBoth ( EBBoth a1 a2) = a1 <> a2
142
-
143
- pairEitherOrBoth
144
- :: EitherOrBoth a b
145
- -> EitherOrBoth x y
146
- -> Maybe (EitherOrBoth (a , x ) (b , y ))
147
- pairEitherOrBoth ( EBBoth a b) (EBBoth x y) = Just $ EBBoth (a, x) (b, y)
148
- pairEitherOrBoth ( EBFirst a) ( EBFirst x) = Just $ EBFirst (a, x)
149
- pairEitherOrBoth ( EBBoth a _) (EBFirst x) = Just $ EBFirst (a, x)
150
- pairEitherOrBoth ( EBFirst a) ( EBBoth x _) = Just $ EBFirst (a, x)
151
- pairEitherOrBoth ( EBSecond b) ( EBSecond y) = Just $ EBSecond (b, y)
152
- pairEitherOrBoth ( EBBoth _ b) (EBSecond y) = Just $ EBSecond (b, y)
153
- pairEitherOrBoth ( EBSecond b) ( EBBoth _ y) = Just $ EBSecond (b, y)
154
- pairEitherOrBoth _ _ = Nothing
110
+ foldThese ( This a) = a
111
+ foldThese ( That a) = a
112
+ foldThese ( These a1 a2) = a1 <> a2
113
+
114
+ pairThese
115
+ :: These a b
116
+ -> These x y
117
+ -> Maybe (These (a , x ) (b , y ))
118
+ pairThese ( These a b) (These x y) = Just $ These (a, x) (b, y)
119
+ pairThese ( This a) ( This x) = Just $ This (a, x)
120
+ pairThese ( These a _) (This x) = Just $ This (a, x)
121
+ pairThese ( This a) ( These x _) = Just $ This (a, x)
122
+ pairThese ( That b) ( That y) = Just $ That (b, y)
123
+ pairThese ( These _ b) (That y) = Just $ That (b, y)
124
+ pairThese ( That b) ( These _ y) = Just $ That (b, y)
125
+ pairThese _ _ = Nothing
155
126
156
127
-- |
157
128
-- Store created sockets. If system supports IPv6 and IPv4 we create socket for
158
129
-- IPv4 and IPv6. Otherwise only one.
159
- type Sockets = EitherOrBoth
130
+ type Sockets = These
160
131
(Last (WithAddrFamily 'IPv6 Socket ))
161
132
(Last (WithAddrFamily 'IPv4 Socket ))
162
133
163
134
-- |
164
135
-- A counter part of @'Ntp.Client.Sockets'@ data type.
165
- type Addresses = EitherOrBoth
136
+ type Addresses = These
166
137
(First (WithAddrFamily 'IPv6 SockAddr ))
167
138
(First (WithAddrFamily 'IPv4 SockAddr ))
168
139
@@ -190,7 +161,7 @@ resolveHost host = do
190
161
let g :: First (WithAddrFamily t SockAddr ) -> [SockAddr ]
191
162
g (First a) = [runWithAddrFamily a]
192
163
addrs :: [SockAddr ]
193
- addrs = foldEitherOrBoth . bimap g g $ addr
164
+ addrs = foldThese . bimap g g $ addr
194
165
in logInfo $ sformat (" Host " % shown% " is resolved: " % shown)
195
166
host addrs
196
167
return maddr
@@ -199,9 +170,9 @@ resolveHost host = do
199
170
fn :: AddrInfo -> Option Addresses
200
171
fn addr = case Socket. addrFamily addr of
201
172
Socket. AF_INET6 ->
202
- Option $ Just $ EBFirst $ First $ (WithIPv6 $ Socket. addrAddress addr)
173
+ Option $ Just $ This $ First $ (WithIPv6 $ Socket. addrAddress addr)
203
174
Socket. AF_INET ->
204
- Option $ Just $ EBSecond $ First $ (WithIPv4 $ Socket. addrAddress addr)
175
+ Option $ Just $ That $ First $ (WithIPv4 $ Socket. addrAddress addr)
205
176
_ -> mempty
206
177
207
178
resolveNtpHost :: String -> IO (Maybe Addresses )
@@ -240,8 +211,8 @@ createAndBindSock addressFamily addrs =
240
211
sformat (" Created socket (family/addr): " % shown% " /" % shown)
241
212
(addrFamily addr) (addrAddress addr)
242
213
case addressFamily of
243
- IPv6 -> return $ EBFirst $ Last $ (WithIPv6 sock)
244
- IPv4 -> return $ EBSecond $ Last $ (WithIPv4 sock)
214
+ IPv6 -> return $ This $ Last $ (WithIPv6 sock)
215
+ IPv4 -> return $ That $ Last $ (WithIPv4 sock)
245
216
246
217
udpLocalAddresses :: IO [AddrInfo ]
247
218
udpLocalAddresses = do
@@ -268,7 +239,7 @@ sendTo
268
239
-> Addresses
269
240
-- ^ addresses to send to
270
241
-> IO ()
271
- sendTo sock bs addr = case fmap (foldEitherOrBoth . bimap fn fn) $ pairEitherOrBoth sock addr of
242
+ sendTo sock bs addr = case fmap (foldThese . bimap fn fn) $ pairThese sock addr of
272
243
Just io -> io
273
244
Nothing -> throw NoMatchingSocket
274
245
where
@@ -309,11 +280,11 @@ sendPacket sock packet addrs = do
309
280
case (addr, addressFamily) of
310
281
-- try to send the packet to the other address in case the current
311
282
-- system does not support IPv4/6.
312
- (EBBoth _ r, IPv6 ) -> do
283
+ (These _ r, IPv6 ) -> do
313
284
logDebug $ sformat (" sendPacket re-sending using: " % shown) (runWithAddrFamily $ getFirst r)
314
- sendPacket sock packet [EBSecond r]
315
- (EBBoth l _, IPv4 ) -> do
285
+ sendPacket sock packet [That r]
286
+ (These l _, IPv4 ) -> do
316
287
logDebug $ sformat (" sendPacket re-sending using: " % shown) (runWithAddrFamily $ getFirst l)
317
- sendPacket sock packet [EBFirst l]
288
+ sendPacket sock packet [This l]
318
289
_ ->
319
290
logDebug " sendPacket: not retrying"
0 commit comments