disco-0.2: src/Disco/Exhaustiveness/Possibilities.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- |
-- Module : Disco.Exhaustiveness.Possibilities
-- Copyright : disco team and contributors
-- Maintainer : byorgey@gmail.com
--
-- SPDX-License-Identifier: BSD-3-Clause
--
-- Meaningful types and functions for describing
-- combinations of different possible options.
module Disco.Exhaustiveness.Possibilities (Possibilities, retSingle, allCombinations, anyOf, none, getPossibilities) where
import Data.Foldable (fold)
newtype Possibilities a = Possibilities {getPossibilities :: [a]}
deriving (Show, Eq, Ord, Functor, Semigroup, Monoid, Applicative)
anyOf :: [Possibilities a] -> Possibilities a
anyOf = fold
none :: Possibilities a -> Bool
none = null . getPossibilities
retSingle :: (Monad m) => a -> m (Possibilities a)
retSingle i = return $ Possibilities [i]
-- | List all possible paths through the list of Possibilites
--
-- Ex.
-- > allCombinations
-- [ Possibilities [1]
-- , Possibilities [2,3]
-- , Possibilities [4]
-- , Possibilities [5,6,7]
-- ]
-- ===
-- Possibilities {getPossibilities =
-- [[1,2,4,5]
-- ,[1,2,4,6]
-- ,[1,2,4,7]
-- ,[1,3,4,5]
-- ,[1,3,4,6]
-- ,[1,3,4,7]
-- ]}
--
-- 2 5
-- / \ /
-- 1 4 --6
-- \ / \
-- 3 7
--
-- If any any of the Possibilities is empty,
-- an empty Possibility is returned
--
-- In other words, this lists all elements of the
-- cartesian product of multiple sets
allCombinations :: [Possibilities a] -> Possibilities [a]
allCombinations = sequenceA