1 {-# OPTIONS_GHC -fno-warn-orphans #-}
2 module Voting.Protocol.Utils where
4 import Control.Applicative (Applicative(..))
5 import Control.Arrow (first)
7 import Data.Either (Either(..), either)
8 import Data.Eq (Eq(..))
9 import Data.Foldable (sequenceA_)
10 import Data.Function (($), (.))
11 import Data.Functor ((<$))
12 import Data.Maybe (Maybe(..), maybe, listToMaybe)
13 import Data.String (String)
14 import Data.Traversable (Traversable(..))
15 import Data.Tuple (uncurry)
16 import Numeric.Natural (Natural)
17 import Prelude (Integer, fromIntegral)
18 import qualified Data.Aeson.Internal as JSON
19 import qualified Data.List as List
20 import qualified System.Random as Random
21 import qualified Text.ParserCombinators.ReadP as Read
23 -- | Like ('.') but with two arguments.
24 o2 :: (c -> d) -> (a -> b -> c) -> a -> b -> d
25 o2 f g = \x y -> f (g x y)
29 -- | NOTE: check the lengths before applying @f@.
30 isoZipWith :: (a->b->c) -> [a]->[b]->Maybe [c]
32 | List.length as /= List.length bs = Nothing
33 | otherwise = Just (List.zipWith f as bs)
35 -- | NOTE: check the lengths before applying @f@.
36 isoZipWith3 :: (a->b->c->d) -> [a]->[b]->[c]->Maybe [d]
37 isoZipWith3 f as bs cs
38 | al /= List.length bs = Nothing
39 | al /= List.length cs = Nothing
40 | otherwise = Just (List.zipWith3 f as bs cs)
41 where al = List.length as
45 f () -> (a->b->f c) -> [a]->[b]->f [c]
46 isoZipWithM err f as bs =
47 maybe ([] <$ err) sequenceA $
52 f () -> (a->b->f c) -> [a]->[b]->f ()
53 isoZipWithM_ err f as bs =
54 maybe err sequenceA_ $
59 f () -> (a->b->c->f d) -> [a]->[b]->[c]->f [d]
60 isoZipWith3M err f as bs cs =
61 maybe ([] <$ err) sequenceA $
62 isoZipWith3 f as bs cs
66 f () -> (a->b->c->f d) -> [a]->[b]->[c]->f ()
67 isoZipWith3M_ err f as bs cs =
68 maybe err sequenceA_ $
69 isoZipWith3 f as bs cs
73 -- | Copied from 'Data.Aeson''s 'eitherFormatError'
74 -- which is not exported.
75 jsonEitherFormatError :: Either (JSON.JSONPath, String) a -> Either String a
76 jsonEitherFormatError = either (Left . uncurry JSON.formatError) Right
77 {-# INLINE jsonEitherFormatError #-}
79 instance Random.Random Natural where
81 first (fromIntegral::Integer -> Natural) .
82 Random.randomR (fromIntegral mini, fromIntegral maxi)
83 random = first (fromIntegral::Integer -> Natural) . Random.random
87 parseReadP :: Read.ReadP a -> String -> Maybe a
89 let p' = Read.readP_to_S p in