code-conjure-0.5.16: synthesize Haskell functions out of partial definitions
Copyright(c) 2021-2024 Rudy Matela
License3-Clause BSD (see the file LICENSE)
MaintainerRudy Matela <[email protected]>
Safe HaskellNone
LanguageHaskell2010

Conjure.Utils

Description

An internal module of Conjure. This exports List, Maybe, Function and a few other simple utitilites.

Synopsis

Documentation

module Data.List

module Data.Maybe

data Solo a where #

Solo is the canonical lifted 1-tuple, just like (,) is the canonical lifted 2-tuple (pair) and (,,) is the canonical lifted 3-tuple (triple).

The most important feature of Solo is that it is possible to force its "outside" (usually by pattern matching) without forcing its "inside", because it is defined as a datatype rather than a newtype. One situation where this can be useful is when writing a function to extract a value from a data structure. Suppose you write an implementation of arrays and offer only this function to index into them:

index :: Array a -> Int -> a

Now imagine that someone wants to extract a value from an array and store it in a lazy-valued finite map/dictionary:

insert "hello" (arr index 12) m

This can actually lead to a space leak. The value is not actually extracted from the array until that value (now buried in a map) is forced. That means the entire array may be kept live by just that value! Often, the solution is to use a strict map, or to force the value before storing it, but for some purposes that's undesirable.

One common solution is to include an indexing function that can produce its result in an arbitrary Applicative context:

indexA :: Applicative f => Array a -> Int -> f a

When using indexA in a pure context, Solo serves as a handy Applicative functor to hold the result. You could write a non-leaky version of the above example thus:

case arr indexA 12 of
  Solo a -> insert "hello" a m

While such simple extraction functions are the most common uses for unary tuples, they can also be useful for fine-grained control of strict-spined data structure traversals, and for unifying the implementations of lazy and strict mapping functions.

Bundled Patterns

pattern Solo :: a -> Solo a 

Instances

Instances details
MonadFix Solo

Since: base-4.15

Instance details

Defined in Control.Monad.Fix

Methods

mfix :: (a -> Solo a) -> Solo a #

MonadZip Solo

Since: base-4.15.0.0

Instance details

Defined in Control.Monad.Zip

Methods

mzip :: Solo a -> Solo b -> Solo (a, b) #

mzipWith :: (a -> b -> c) -> Solo a -> Solo b -> Solo c #

munzip :: Solo (a, b) -> (Solo a, Solo b) #

Foldable Solo

Since: base-4.15

Instance details

Defined in Data.Foldable

Methods

fold :: Monoid m => Solo m -> m #

foldMap :: Monoid m => (a -> m) -> Solo a -> m #

foldMap' :: Monoid m => (a -> m) -> Solo a -> m #

foldr :: (a -> b -> b) -> b -> Solo a -> b #

foldr' :: (a -> b -> b) -> b -> Solo a -> b #

foldl :: (b -> a -> b) -> b -> Solo a -> b #

foldl' :: (b -> a -> b) -> b -> Solo a -> b #

foldr1 :: (a -> a -> a) -> Solo a -> a #

foldl1 :: (a -> a -> a) -> Solo a -> a #

toList :: Solo a -> [a] #

null :: Solo a -> Bool #

length :: Solo a -> Int #

elem :: Eq a => a -> Solo a -> Bool #

maximum :: Ord a => Solo a -> a #

minimum :: Ord a => Solo a -> a #

sum :: Num a => Solo a -> a #

product :: Num a => Solo a -> a #

Foldable1 Solo

Since: base-4.18.0.0

Instance details

Defined in Data.Foldable1

Methods

fold1 :: Semigroup m => Solo m -> m #

foldMap1 :: Semigroup m => (a -> m) -> Solo a -> m #

foldMap1' :: Semigroup m => (a -> m) -> Solo a -> m #

toNonEmpty :: Solo a -> NonEmpty a #

maximum :: Ord a => Solo a -> a #

minimum :: Ord a => Solo a -> a #

head :: Solo a -> a #

last :: Solo a -> a #

foldrMap1 :: (a -> b) -> (a -> b -> b) -> Solo a -> b #

foldlMap1' :: (a -> b) -> (b -> a -> b) -> Solo a -> b #

foldlMap1 :: (a -> b) -> (b -> a -> b) -> Solo a -> b #

foldrMap1' :: (a -> b) -> (a -> b -> b) -> Solo a -> b #

Eq1 Solo

Since: base-4.15

Instance details

Defined in Data.Functor.Classes

Methods

liftEq :: (a -> b -> Bool) -> Solo a -> Solo b -> Bool #

Ord1 Solo

Since: base-4.15

Instance details

Defined in Data.Functor.Classes

Methods

liftCompare :: (a -> b -> Ordering) -> Solo a -> Solo b -> Ordering #

Read1 Solo

Since: base-4.15

Instance details

Defined in Data.Functor.Classes

Methods

liftReadsPrec :: (Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (Solo a) #

liftReadList :: (Int -> ReadS a) -> ReadS [a] -> ReadS [Solo a] #

liftReadPrec :: ReadPrec a -> ReadPrec [a] -> ReadPrec (Solo a) #

liftReadListPrec :: ReadPrec a -> ReadPrec [a] -> ReadPrec [Solo a] #

Show1 Solo

Since: base-4.15

Instance details

Defined in Data.Functor.Classes

Methods

liftShowsPrec :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> Solo a -> ShowS #

liftShowList :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> [Solo a] -> ShowS #

Traversable Solo

Since: base-4.15

Instance details

Defined in Data.Traversable

Methods

traverse :: Applicative f => (a -> f b) -> Solo a -> f (Solo b) #

sequenceA :: Applicative f => Solo (f a) -> f (Solo a) #

mapM :: Monad m => (a -> m b) -> Solo a -> m (Solo b) #

sequence :: Monad m => Solo (m a) -> m (Solo a) #

Applicative Solo

Since: base-4.15

Instance details

Defined in GHC.Base

Methods

pure :: a -> Solo a #

(<*>) :: Solo (a -> b) -> Solo a -> Solo b #

liftA2 :: (a -> b -> c) -> Solo a -> Solo b -> Solo c #

(*>) :: Solo a -> Solo b -> Solo b #

(<*) :: Solo a -> Solo b -> Solo a #

Functor Solo

Since: base-4.15

Instance details

Defined in GHC.Base

Methods

fmap :: (a -> b) -> Solo a -> Solo b #

(<$) :: a -> Solo b -> Solo a #

Monad Solo

Since: base-4.15

Instance details

Defined in GHC.Base

Methods

(>>=) :: Solo a -> (a -> Solo b) -> Solo b #

(>>) :: Solo a -> Solo b -> Solo b #

return :: a -> Solo a #

Generic1 Solo 
Instance details

Defined in GHC.Generics

Associated Types

type Rep1 Solo

Since: base-4.15

Instance details

Defined in GHC.Generics

type Rep1 Solo = D1 ('MetaData "Solo" "GHC.Tuple.Prim" "ghc-prim" 'False) (C1 ('MetaCons "MkSolo" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) Par1))

Methods

from1 :: Solo a -> Rep1 Solo a #

to1 :: Rep1 Solo a -> Solo a #

Data a => Data (Solo a)

Since: base-4.15

Instance details

Defined in Data.Data

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Solo a -> c (Solo a) #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Solo a) #

toConstr :: Solo a -> Constr #

dataTypeOf :: Solo a -> DataType #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Solo a)) #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Solo a)) #

gmapT :: (forall b. Data b => b -> b) -> Solo a -> Solo a #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Solo a -> r #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Solo a -> r #

gmapQ :: (forall d. Data d => d -> u) -> Solo a -> [u] #

gmapQi :: Int -> (forall d. Data d => d -> u) -> Solo a -> u #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> Solo a -> m (Solo a) #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Solo a -> m (Solo a) #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Solo a -> m (Solo a) #

Monoid a => Monoid (Solo a)

Since: base-4.15

Instance details

Defined in GHC.Base

Methods

mempty :: Solo a #

mappend :: Solo a -> Solo a -> Solo a #

mconcat :: [Solo a] -> Solo a #

Semigroup a => Semigroup (Solo a)

Since: base-4.15

Instance details

Defined in GHC.Base

Methods

(<>) :: Solo a -> Solo a -> Solo a #

sconcat :: NonEmpty (Solo a) -> Solo a #

stimes :: Integral b => b -> Solo a -> Solo a #

Bounded a => Bounded (Solo a) 
Instance details

Defined in GHC.Enum

Methods

minBound :: Solo a #

maxBound :: Solo a #

Enum a => Enum (Solo a) 
Instance details

Defined in GHC.Enum

Methods

succ :: Solo a -> Solo a #

pred :: Solo a -> Solo a #

toEnum :: Int -> Solo a #

fromEnum :: Solo a -> Int #

enumFrom :: Solo a -> [Solo a] #

enumFromThen :: Solo a -> Solo a -> [Solo a] #

enumFromTo :: Solo a -> Solo a -> [Solo a] #

enumFromThenTo :: Solo a -> Solo a -> Solo a -> [Solo a] #

Generic (Solo a) 
Instance details

Defined in GHC.Generics

Associated Types

type Rep (Solo a)

Since: base-4.15

Instance details

Defined in GHC.Generics

type Rep (Solo a) = D1 ('MetaData "Solo" "GHC.Tuple.Prim" "ghc-prim" 'False) (C1 ('MetaCons "MkSolo" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)))

Methods

from :: Solo a -> Rep (Solo a) x #

to :: Rep (Solo a) x -> Solo a #

Ix a => Ix (Solo a) 
Instance details

Defined in GHC.Ix

Methods

range :: (Solo a, Solo a) -> [Solo a] #

index :: (Solo a, Solo a) -> Solo a -> Int #

unsafeIndex :: (Solo a, Solo a) -> Solo a -> Int #

inRange :: (Solo a, Solo a) -> Solo a -> Bool #

rangeSize :: (Solo a, Solo a) -> Int #

unsafeRangeSize :: (Solo a, Solo a) -> Int #

Read a => Read (Solo a)

Since: base-4.15

Instance details

Defined in GHC.Read

Show a => Show (Solo a)

Since: base-4.15

Instance details

Defined in GHC.Show

Methods

showsPrec :: Int -> Solo a -> ShowS #

show :: Solo a -> String #

showList :: [Solo a] -> ShowS #

Eq a => Eq (Solo a) 
Instance details

Defined in GHC.Classes

Methods

(==) :: Solo a -> Solo a -> Bool #

(/=) :: Solo a -> Solo a -> Bool #

Ord a => Ord (Solo a) 
Instance details

Defined in GHC.Classes

Methods

compare :: Solo a -> Solo a -> Ordering #

(<) :: Solo a -> Solo a -> Bool #

(<=) :: Solo a -> Solo a -> Bool #

(>) :: Solo a -> Solo a -> Bool #

(>=) :: Solo a -> Solo a -> Bool #

max :: Solo a -> Solo a -> Solo a #

min :: Solo a -> Solo a -> Solo a #

type Rep1 Solo

Since: base-4.15

Instance details

Defined in GHC.Generics

type Rep1 Solo = D1 ('MetaData "Solo" "GHC.Tuple.Prim" "ghc-prim" 'False) (C1 ('MetaCons "MkSolo" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) Par1))
type Rep (Solo a)

Since: base-4.15

Instance details

Defined in GHC.Generics

type Rep (Solo a) = D1 ('MetaData "Solo" "GHC.Tuple.Prim" "ghc-prim" 'False) (C1 ('MetaCons "MkSolo" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)))

uncurry :: (a -> b -> c) -> (a, b) -> c #

uncurry converts a curried function to a function on pairs.

Examples

Expand
>>> uncurry (+) (1,2)
3
>>> uncurry ($) (show, 1)
"1"
>>> map (uncurry max) [(1,2), (3,4), (6,8)]
[2,4,8]

getSolo :: Solo a -> a #

Extract the value from a Solo. Very often, values should be extracted directly using pattern matching, to control just what gets evaluated when. getSolo is for convenience in situations where that is not the case:

When the result is passed to a strict function, it makes no difference whether the pattern matching is done on the "outside" or on the "inside":

Data.Set.insert (getSolo sol) set === case sol of Solo v -> Data.Set.insert v set

A traversal may be performed in Solo in order to control evaluation internally, while using getSolo to extract the final result. A strict mapping function, for example, could be defined

map' :: Traversable t => (a -> b) -> t a -> t b
map' f = getSolo . traverse ((Solo $!) . f)

fst :: (a, b) -> a #

Extract the first component of a pair.

snd :: (a, b) -> b #

Extract the second component of a pair.

curry :: ((a, b) -> c) -> a -> b -> c #

curry converts an uncurried function to a curried function.

Examples

Expand
>>> curry fst 1 2
1

swap :: (a, b) -> (b, a) #

Swap the components of a pair.

count :: (a -> Bool) -> [a] -> Int Source #

Counts the number of occurrences on a list.

nubOn :: Eq b => (a -> b) -> [a] -> [a] Source #

Nubs using a given field.

nubSort :: Ord a => [a] -> [a] Source #

Equivalent to nub . sort but running in O(n log n).

mzip :: Monoid a => [a] -> [a] -> [a] Source #

Zips Monoid values leaving trailing values.

> mzip ["ab","cd"] ["ef"]
["abef","cd"]

groupOn :: Eq b => (a -> b) -> [a] -> [[a]] Source #

Group values using a given field selector.

idIO :: (a -> IO ()) -> a -> a Source #

WARNING: uses unsafePerformIO and should only be used for debugging!

> idIO print 10
10
10

mapHead :: (a -> a) -> [a] -> [a] Source #

Applies a function to the head of a list.

sets :: [a] -> [[a]] Source #

Return sets of values based on the list.

The values in the list must me unique.

headOr :: a -> [a] -> a Source #

Like head but allows providing a default value.

allEqual :: Eq a => [a] -> Bool Source #

Checks if all elements of a list are equal.

allEqualOn :: Eq b => (a -> b) -> [a] -> Bool Source #

allEqual2 :: Eq a => [a] -> Bool Source #

Checks if all elements of a list are equal.

Exceptionally this function returns false for an empty or unit list.

This returns true when all elements are equal and the list has a length greater than or equal to two.

choices :: [a] -> [(a, [a])] Source #

Lists choices of values.

choicesThat :: (a -> [a] -> Bool) -> [a] -> [(a, [a])] Source #

Lists choices of values that follow a property.

foldr0 :: (a -> a -> a) -> a -> [a] -> a Source #

A variation of foldr that only uses "zero" when the list is empty

indent :: String -> String Source #

Indents a block of text by 4 spaces

indentBy :: Int -> String -> String Source #

Indents a block of text with the provided amount of spaces

classify :: Eq a => [a] -> [[a]] #

Classify values using their Eq instance.

> classify [1,2,3,1,2,1]
[[1,1,1],[2,2],[3]]

(cf. classifyBy, classifyOn)

classifyBy :: (a -> a -> Bool) -> [a] -> [[a]] #

Classify values by a given comparison function.

> classifyBy (\(x,_) (y,_) -> x == y) [(1,1),(1,2),(2,1),(2,2)]
[[(1,1),(1,2)],[(2,1),(2,2)]]

(cf. classify, classifyOn)

classifyOn :: Eq b => (a -> b) -> [a] -> [[a]] #

Classify values based on the result of a given function.

> classifyOn head ["sheep", "chip", "ship", "cheap"]
[["sheep","ship"],["chip","cheap"]]
> classifyOn odd [1,2,3,4,5,6]
[[1,3,5],[2,4,6]]

(cf. classify, classifyBy)

none :: (a -> Bool) -> [a] -> Bool Source #

updateAt :: Int -> (a -> a) -> [a] -> [a] Source #

Updates the value in a list at a given position.

> updateAt 2 (*10) [1,2,3,4]
[1,2,30,4]

first :: (a -> a') -> (a, b) -> (a', b) Source #

Applies a function to the first element of a pair. Often known on the wild as mapFst.

> first (*10) (1,2)
(10,2)

second :: (b -> b') -> (a, b) -> (a, b') Source #

Applies a function to the second element of a pair. Often known on the wild as mapSnd.

> second (*100) (1,2)
(1,200)

both :: (a -> b) -> (a, a) -> (b, b) Source #

(+++) :: Ord a => [a] -> [a] -> [a] infixr 5 Source #

isSubsetOf :: Ord a => [a] -> [a] -> Bool #

O(n log n). Checks that all elements of the first list are elements of the second.